home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
LSD Docs
/
LSD Docs.iso
/
FILEZ
/
lsd34.dms
/
lsd34.adf
/
AREXX.doc1.pp
/
AREXX.doc1
Wrap
Text File
|
1990-09-13
|
153KB
|
3,567 lines
AREXX USER'S REFERENCE MANUAL
PART 1
TABLE OF CONTENTS
INTRODUCTION....................................................1
1. Organization of this Document...............................1
1 Using this Manual.........................................2
2 Typographic Conventions...................................2
2. Future Directions...........................................2
CHAPTER 1. WHAT IS AREXX?.......................................3
1. Language Features...........................................3
2. ARexx on the Amiga..........................................4
3. Further Information.........................................4
CHAPTER 2. GETTING ACQUAINTED...................................5
1. Installing ARexx............................................5
1 ARexx and Workbench.......................................5
2 Installation..............................................5
3 Starting the Resident Process.............................6
4 Naming Conventions........................................6
5 The REXX: Directory.......................................6
2. Program Examples............................................7
CHAPTER 3. ELEMENTS OF THE LANGUAGE............................11
1. Format.....................................................11
2. Tokens.....................................................11
1 Comment Tokens...........................................11
2 Symbol Tokens............................................11
3 String Tokens............................................12
4 Operators................................................12
5 Special Character Tokens.................................13
3. Clauses....................................................14
1 Null Clauses.............................................14
2 Label Clauses............................................14
3 Assignment Clauses.......................................14
4 Instruction Clauses......................................15
5 Command Clauses..........................................15
6 Clause Classification....................................15
4. Expressions................................................16
1 Symbol Resolution........................................16
2 Order of Evaluation......................................16
5. Numbers and Numeric Precision..............................17
1 Boolean Values...........................................17
2 Numeric Precision........................................17
6. Operators..................................................18
1 Arithmetic Operators.....................................18
2 Concatenation Operators..................................20
3 Comparison Operators.....................................20
4 Logical (Boolean) Operators..............................21
7. Stems and Compound Symbols.................................21
i
CHAPTER 3. ELEMENTS OF THE LANGUAGE (CONT).....................11
8. The Execution Environment..................................22
1 The External Environment.................................22
2 The Internal Environment.................................22
3 Input and Output.........................................23
4 Resource Tracking........................................24
CHAPTER 4. INSTRUCTIONS........................................25
1. ADDRESS....................................................25
2. ARG........................................................25
3. BREAK......................................................26
4. CALL.......................................................26
5. DO.........................................................27
6. DROP.......................................................28
7. ECHO.......................................................28
8. ELSE.......................................................28
9. END........................................................29
10. EXIT......................................................29
11. IF........................................................29
12. INTERPRET.................................................30
13. ITERATE...................................................30
14. LEAVE.....................................................31
15. NOP.......................................................31
16. NUMERIC...................................................31
17. OPTIONS...................................................32
18. OTHERWISE.................................................32
19. PARSE.....................................................33
1 Input Sources...........................................33
2 Templates...............................................34
20. PROCEDURE.................................................35
21. PULL......................................................35
22. PUSH......................................................36
23. QUEUE.....................................................37
24. RETURN....................................................37
25. SAY.......................................................38
26. SELECT....................................................38
27. SHELL.....................................................38
28. SIGNAL....................................................38
29. THEN......................................................39
30. TRACE.....................................................40
31. UPPER.....................................................40
32. WHEN......................................................41
CHAPTER 5. COMMANDS............................................43
1. Command Clauses............................................43
2. The Host Address...........................................44
3. The Command Interface......................................44
4. Using Commands in Macro Programs...........................45
5. Using ARexx with Command Shells............................45
6. Command Inhibition.........................................46
ii
CHAPTER 6. FUNCTIONS...........................................47
1. Syntax and Search Order....................................47
1 Search Order.............................................47
2 Internal Functions.......................................48
3 Built-In Functions.......................................49
4 External Function Libraries..............................49
5 Function Hosts...........................................50
2. The Built-In Function Library..............................50
1 ABBREV().................................................51
2 ABS()....................................................51
3 ADDLIB().................................................51
4 ADDRESS()................................................51
5 ARG()....................................................52
6 B2C()....................................................52
7 BITAND().................................................52
8 BITCHG().................................................52
9 BITCLR().................................................53
10 BITCOMP()...............................................53
11 BITOR().................................................53
12 BITSET()................................................53
13 BITTST()................................................53
14 BITXOR()................................................54
15 C2B()...................................................54
16 C2D()...................................................54
17 C2X()...................................................54
18 CENTER() OR CENTRE()....................................55
19 CLOSE().................................................55
20 COMPRESS()..............................................55
21 COMPARE()...............................................55
22 COPIES()................................................55
23 D2C()...................................................56
24 DATATYPE()..............................................56
25 DELSTR()................................................56
26 DELWORD()...............................................57
27 EOF()...................................................57
28 ERRORTEXT().............................................57
29 EXISTS()................................................57
30 EXPORT()................................................57
31 FREESPACE().............................................58
32 GETCLIP()...............................................58
33 GETSPACE()..............................................58
34 HASH()..................................................58
35 IMPORT()................................................59
36 INDEX().................................................59
37 INSERT()................................................59
38 LASTPOS()...............................................59
39 LEFT()..................................................60
40 LENGTH()................................................60
iii
41 MAX()...................................................60
42 MIN()...................................................60
43 OPEN()..................................................60
44 OVERLAY()...............................................61
45 POS()...................................................61
46 PRAGMA()................................................61
47 RANDOM()................................................62
48 RANDU().................................................62
49 READCH()................................................62
50 READLN()................................................63
51 REMLIB()................................................63
52 REVERSE()...............................................63
53 RIGHT().................................................63
54 SEEK()..................................................63
55 SETCLIP()...............................................64
56 SHOW()..................................................64
57 SIGN()..................................................64
58 SPACE().................................................64
59 STORAGE()...............................................65
60 STRIP().................................................65
61 SUBSTR()................................................65
62 SUBWORD()...............................................66
63 SYMBOL()................................................66
64 TIME()..................................................66
65 TRACE().................................................67
66 TRANSLATE().............................................67
67 TRIM()..................................................67
68 UPPER().................................................67
69 VALUE().................................................68
70 VERIFY()................................................68
71 WORD()..................................................68
72 WORDINDEX().............................................68
73 WORDLENGTH()............................................68
74 WORDS().................................................69
75 WRITECH()...............................................69
76 WRITELN()...............................................69
77 X2C()...................................................69
78 XRANGE()................................................69
CHAPTER 7. TRACING AND INTERRUPTS..............................71
1. Tracing Options............................................71
2. Display Formatting.........................................72
1 Tracing Output...........................................72
2 Command Inhibition.......................................73
3. Interactive Tracing........................................73
1 Error Processing.........................................74
2 The External Tracing Flag................................74
4. Interrupts.................................................74
iv
CHAPTER I. PARSING AND TEMPLATES...............................77
1. Template Structure.........................................77
1 Template Objects.........................................78
2 The Scanning Process.....................................78
2. Templates in Action........................................79
1 Parsing by Tokenization..................................79
2 Pattern Parsing..........................................80
3 Positional Markers.......................................80
4 Multiple Templates.......................................80
CHAPTER 9. THE RESIDENT PROCESS................................83
1. Command Utilities..........................................83
1 HI.......................................................83
2 RX.......................................................84
3 RXSET....................................................84
4 RXC......................................................84
5 TCC......................................................84
6 TCO......................................................84
7 TE.......................................................84
8 TS.......................................................84
2. Resource Management........................................85
1 The Global Tracing Console...............................85
2 The Library List.........................................85
3 The Clip List............................................86
CHAPTER 10. INTERFACING TO AREXX...............................89
1. Basic Structers............................................90
2. Designing a Command Interface..............................91
1 Receiving Command Messages...............................92
2 Result Fields............................................92
3 Multiple Host Processes..................................92
3. Invoking ARexx Programs....................................93
1 Message Packets..........................................93
2 Command Invocations......................................94
3 Function Invocations.....................................95
4 Search Order.............................................95
5 Extension Fields.........................................96
6 Interpreting the Result Fields...........................97
4. Communicating with the Resident Process....................97
1 Command (Action) Codes...................................97
2 Modifier Flags...........................................99
3 Result Fields...........................................100
5. External Function Libraries...............................100
1 Design Considerations...................................100
2 Calling Convention......................................101
3 Parameter Conversion....................................101
4 Returned Values.........................................101
6. Direct Manipulation of Data Structures....................102
v
APPENDIX A. ERROR MESSAGES....................................103
APPENDIX B. LIMITS AND COMPATIBILITY..........................109
1 Limits.....................................................109
2 Compatibility..............................................109
APPENDIX C. THE AREXX SYSTEMS LIBRARY.........................111
1 Functional Groups..........................................111
2 Library Functions..........................................113
APPENDIX D. THE AREXX SUPPORT LIBRARY.........................127
1 ALLOCMEM()...............................................127
2 CLOSEPORT()..............................................127
3 FREEMEM()................................................128
4 GETARG().................................................128
5 GETPKT().................................................128
6 OPENPORT()...............................................128
7 REPLY()..................................................129
8 SHOWDIR()................................................129
9 SHOWLIST()...............................................129
10 STATEF()................................................130
11 WAITPKT()...............................................130
APPENDIX E. DISTRIBUTION FILES................................131
1 Directories................................................131
1 The :C Directory.........................................131
2 The :INCLUDE Directory...................................131
3 The :LIBS Directory......................................132
4 The :REXX Directory......................................132
5 The :TOOLS Directory.....................................132
6 Miscellaneous Files......................................132
2 Listings of Header Files...................................133
1 storage.h................................................133
2 rxslib.h.................................................139
3 rexxio.h.................................................142
4 errors.h.................................................144
GLOSSARY......................................................147
INDEX.........................................................151
vi
INTRODUCTION
Welcome to ARexx,an implementation of the REXX language for the Amiga computer.
ARexx is a powerful programming took,but one which by virtue of its clean
syntax and sparse vocabulary is also easy to learn and easy to use.
1 ORGANIZATION OF THIS DOCUMENT
This document will attempt to fill the roles of User's Manual,Language
Reference,and Programmer's Guide. The chapters that follow have been organized
to provide a gently introduction to the language.
Chapter 1,What is ARexx?,gives an overview of the ARexx language and its
implementation of the Amiga.
Chapter 2,Getting Acquainted,tells how to install ARexx on your Amiga and
presents several example programs to illustrate the features of the language.
Chapter 3,Elements of the Language,introduces the language structure and
syntax.
Chapter 4,Instructions,describes the action statements of ARexx.
Chapter 5,Commands,describes the program statements used to communicate with
external programs.
Chapter 6,Functions,explains how functions are called and documents the Built-
In Function library.
Chapter 7,Tracing and Interrupts,describes the source level debugging features
useful for developing and testing programs.
Chapter 8,Parsing and Templates,describes the instructions used to extract
words or fields from strings.
Chapter 9,The Resident Process,describes the capabilities of the global
communications and resources manager.
Chapter 10,Interfacing to ARexx,describes how to design and implement an
interface between ARexx and an external program.
Appendix A,Error Messages,lists the error messages issued by the interpreter.
Appendix B,Limits and Compatibility,discusses the compatibility of ARexx with
the language standard.
Appendix C,The ARexx Systems Library,documents the functions of ARexx systems
library.
Appendix D,The Support Library,documents the library of Amiga specific
functions.
Appendix E,Distribution Files,lists the files on the distribution disk.
Finally,a Glossary and an Index are provided.
1
USING THIS MANUAL
If you are new to the REXX language,or perhaps to programming itself,you should
review chapters 1 through 4 and then play with ARexx by running some of the
sample programs given in chapter 2. Further examples are available in the :rexx
directory of the distribution disk.
If you are already familiar with REXX you may wish to skip directly to chapter
5,which begins to present some of the system-dependent features of this
implementation. A summary of the compatibility of ARexx with the language
definition is contained in Appendix B.
TYPOGRAPHIC CONVENTIONS
Describing a language is sometimes difficult because of the multiple and
changing contexts involved. To help clarify the presentation here,a simply
typographic convention has been adopted throughout the document. All of the
terms and words specific to the REXX language,as well as the program examples
and computer input and output,have been set in typewriter font like this. This
should help to distinguish the language keywords and examples from the
surrounding text.
2 FUTURE DIRECTIONS
ARexx,like most software products,will probably envolve somewhat over the next
few years as new features are added,old bugs are removed,and market imperatives
become more apparant. While the core language will probably undergo few
modifications,many capabilities will be added to the function libraries
supported by ARexx. Your comments and suggestions for improvements to ARexx are
most welcome.
The author sincerely hopes that other software developers will consider using
ARexx with their products. The advantages of having a rich variety of software
products sharing a common user interface and a common procedural interface
cannot be overstated. This is the underlying promise of the Amiga's
multitasking capability,and that which most sets it apart from other
inexpensive computers.
Example Programs. One of the best ways to learn a computer language is to study
examples written by more experienced programmers. The ARexx distribution disk
includes a few example programs in the :rexx directory,and more programs will
be added in future releases.
If you have written REXX language program(for any computer)that you think would
be of interest to a more general audience,please send it to the author for
consideration. Programs should be of interest either in terms of their specific
funtionality or as an example of programming technique. Each program submitted
should include an author credit and a few lines of commentary on its intended
fuction.
2
ARexx is a high-level language useful for prototyping,software integration,and
general programming tasks. It is an implementation of the REXX language
described by M.F. Cowlishaw in The REXX Language:A Practical Approach to
Programming(Prentice-Hall,1985),and follow the language definition closely.
ARexx is particularly well suited as a command language. Command programs,
sometimes called "scripts" or "macros",are widely used to extend the predefined
commands of an operating system or to customize an applications program.
As a programming language,ARexx can be useful to a wide cross section of users.
For the novice programmer,ARexx is an easy-to-learn yet powerful language that
serves as a good introduction to programming techniques. Its source-level
debugging facilities will help take some of the mystery out of how programs
work(or don't work,as is more frequently the case.)
For the more sophisticated user,ARexx provides the means to build fully
integrated software packages,combining different applications programs into an
environment tailored to their needs. A common command language among
applications that support ARexx will bring uniformity to procedural interfaces,
much as the Amiga's Intuition provides uniformity in the graphical interface.
Finally,for the software developer,ARexx offers a straightforward way to build
fully programmable applications programs. Developers can concentrate their
efforts on making the basic operations of their programs fast and efficient,and
let the end user add the frills and custom features.
1-1 LANGUAGE FEATURES
Some of the important features of the language are:
TYPELESS DATA. Data are treated as typeless character strings. Variables do not
have to be declared before being used,and all operations dynamically check the
validity of the operands.
COMMAND INTERFACE. ARexx programs can issue commands to external programs that
provide a suitable command interface. Any software package that implements the
command interface is then fully programmable using ARexx,and can be extended
and customized by the end user.
TRACING AND DEBUGGING. ARexx includes source-level debugging facilities that
allow the programmer to see the step-by-step actions of a program as it runs,
thereby reducing the time required to develop and test programs. An internal
interrupt system permits special handling of errors that would otherwise cause
the program to terminate.
3
INTERPRETED EXECUTION. ARexx programs are run by an interpreter,so separate
compilation and linking steps are not required. This makes it especially useful
for prototyping and as a learning tool.
FUNCTION LIBRARIES. External function libraries can be used to extend the
capabilities of the language or as bridges to other programs. Libraries also
allow ARexx programs to be used as "test drivers" for software development and
testing.
AUTOMATIC RESOURCE MANAGEMENT. Internal memory allocation related to the
creation and destruction of strings and other data structures is handled
automatically.
1-2 AREXX ON THE AMIGA
ARexx was designed to run on the Amiga,and makes use of many of the features of
its multitasking operating system. ARexx programs run as separate tasks and
may communicate with each other or with external programs. The interpreter
follows the design guidelines expected of well-behaved programs in a
multitasking environment: specifcally,it uses as little memory as possible and
is careful to reutrn resources to the operating system when they are no longer
needed. Memory requirements were minimized by implementing the entire ARexx
system as a shared library,so that only one copy of the program code must be
loaded.
1-3 FURTHER INFORMATION
The aforementioned book by M.F. Cowlishaw is highly recommended to those
interested in further information about REXX. It presents an interesting
discussion of the design and development of the language.
4
CHAPTER 2 GETTING ACQUAINTED
This chapter explains how to install ARexx on your Amiga computer and shows
some example programs.
2-1 INSTALLING AREXX
ARexx requires an Amiga computer with at least 256k of memory,and will operate
under V1.1 or V1.2 of the operating system. It uses the double-precision math
library called "mathieeedoubbas.library" that is supplied with the Amiga
WorkBench disk,so make sure that this file is present in your LIBS: directory.
The distribution disk includes the language system,some example programs,and a
set of the INCLUDE files required for integrating ARexx with other software
packages. The distribution files are listed in Appendix E.
AREXX AND WORKBENCH
ARexx can be installed and loaded from within the icon-based environment
provided by the Amiga WorkBench. However,it is a primarily a text-oriented
language system and requires a good text editor and file management environment
to be most effective. Unless you purchased ARexx as part of an applications
package that includes an integrated editor,you'll probably find it useful to
become familiar with the Commmand Line Interface (CLI)environment on the Amiga.
INSTALLATION
The ARexx language system consists of a shared library,a resident program,and
several command utilities. All of the required files are contained in the :c
and :libs directories of the distribution disk. ARexx may be installed on any
of the system disks with which it will be used,but first check the :c and :libs
directores of each disk to make sure that there are no naming conflicts. The
following steps will then install ARexx on the system disk,provided that two
disk drives are available:
1. Activate a CLI window.
2. Copy the ARexx :libs directory to the system LIBS: directory with the
command "copy df1:libs to libs:".
3. Copy the ARexx :c directory to the system C: directory with the command
"copy df1:C to c:".
SINGLE DRIVE SYSTEMS. Installing software in a single-drive system can be very
confusing,so an installation utility has been provided with the ARexx
distribution disk. It copies the :c and :libs directories of the distribution
disk into memory,and then prompts the user to insert each disk that is to
receive the files. Follow these steps to run the installation utility:
5
1. Activate a CLI window.
2. Insert the distribution disk into drive 0 and type "df0:rxinstall".
3. At the program prompt,insert the system disk on which ARexx is to be
installed into drive 0.
4. Repeat step 3 as required.
STARTING THE RESIDENT PROCESS
ARexx programs are launched by a background program called the resident
process. It can be started by issuing the command rexxmast and must be active
before any ARexx programs can be run. The rexxmast program briefly displays a
small window to announce itself,and then disappears into the background to
await your next request. If you will be using ARexx frequently,you can place
the rexxmast command in the "startup-sequence" file that resides in the system
S: directory. This will start the resident process automatically when you
reboot the computer.
After the resident process has been loaded,ARexx programs can be run from the
CLI by typing the command rx followed by the program name and any arguments.
For example,the sample program calc.rexx,which evaluates an expression,could be
run by typeing "rx :rexx/calc 1+1."
You may not need to start up the resident process if you are using a software
package that starts it automatically. Applications that use ARexx can test
whether the resident process is active by checking for a public message port
named "REXX." If the port hasn't been opened,the program can issue the rexxmast
command directly.
The resident process can be closed using the command rxc;it will then exit as
soon as the last ARexx program finishes execution. Unless you are very short on
memory space,there is usually no reason to close ARexx,as it simply waits in
the background for the next program to run.
NAMING CONVENTIONS
ARexx programs can be named anything,but adopting a simple naming convention
will make managing the programs much easier. Programs to be run from the CLI
are usually given the file extention .rexx to distinguish them from programs
written in other languages. Programs written as "macros" or "scripts" for a
particular applications program should be given a file extension specific to
that program. For example,a macro written for a communications program called
"MyComm" might be named "download.myc". ARexx uses this file extention when it
searches for a program file to be executed.
THE REXX: DIRECTORY
You can designate one directory as the system-wide source for ARexx programs by
defining a REXX: "device" with the assign command. This directory should reside
on a volume that is usually mounted,such as SYS: or a hard disk. For example,
the command "assign rexx: sys:rexx" defines the REXX: device as the :rexx
directory on the system disk. Once defined,the REXX: device is searched after
the current directory when looking for an ARexx program.
6
2-2 PROGRAM EXAMPLES
Before introducing the structure and syntax of the language,let's look at a few
examples of ARexx programs. Readers familiar with other high-level programming
languages should find many points of similarity between ARexx and other
languages. In the examples that follow,new terms are highlighted in the text as
they are introduced,and will be convered in depth in the next few chapters.
These short programs can be created using any text editor and then run from the
Command Line Interface (CLI),or may simply be read as samples of the language.
If the examples are to be run,first complete the installation procedures
outlined in the previous section,and then start the ARexx resident process.
Example programs can then be run by entering,for example,"rx age" at the CLI
prompt.
We'll begin with a "Hello,World" program that simply displays a message on the
console screen.
/* A simple program */
say 'Hello,World'
This program consists of a comment line that describes the program and an
instruction that displays text on the console. For historical reasons, ARexx
programs begin with a comment line;the initial "/*" says "I'm an ARexx program"
to the interpreter when it searches for a program.
Instructions are language statements that denote a certain action to be
performed,and always start with a symbol,in this case the word say. Symbols are
translated to uppercase when the program is run,so the symbol say here is
equivalent to SAY. Following say is an example of a string,which is a series of
characters surrounded by quotes ('). Double quotes (") could also have been
used to define the string.
In the next program we'll display a prompt for input and then read some
information from the user.
/* Calculate age in days */
say 'Please enter your age'
pull age
say 'You are about' age*365 'days old'
This program uses the pull instruction to read a line of input into a variable
called age,which is then used with a say instuction. Variables are symbols that
may be assigned a value. The words following say form an expression in which
strings are joined and an arithmetic calculation is performed.
Note that the variable age did not have to be declared as a number;instead,its
value was checked when it was actually used in the expression. To see what
would happen if age wasn't a number,try rerunning the program with a
non-numeric entry for the age. The resulting error message shows the line
number and type of error that occurred,after which the program ends.
7
The next program introduces the do instruction,which allows program statements
to be executed repeatedly. It also illustrates the exponentiation operator,
which is used to raise a number to an integral power.
/* Calculate some squares and cubes */
do i = 1 to 10 /* 10 interations */
say i i**2 i**3 /* calculations */
end
say ' all done '
The do instruction causes the statements between the do and end instructions to
be executed 10 times. The variable i is the index variable for the loop,and is
incremented by 1 for each iteration. The number following the symbol to is the
limit for the do instruction,and could have been a full expression rather than
just the constant 10. Note that the statements within the loop have been
indented. This is not required by the language,but it makes the program more
readable and is therefore good programming practice.
The subject of the next example is the if instruction,a often-used control
statement that allows statements to be conditionally executed. The numbers from
1 to 10 are classified as even or odd by dividing them by 2 and then checking
the remainder.
/* Even or odd? */
do i = 1 to 10
if i//2 = 0 then type = 'even'
else type = 'odd'
say i 'is' type
end
This example intoduces the // arithmetic operator,which calculates the
remainder after a division operation. The if instruction tests whether the
remainder is 0 and executes the then branch if it is,thereby setting the
variable type to "even." If the remainder was not 0,the alternative else branch
is executed and type is set to "odd."
The next example introduces the concept of a function,which is a group of
statements that can be executed by mentioning the function name in a suitable
context. Functions are an important part of most programming languages,as they
allow large,complex programs to be built from smaller modules. Functions are
specified in an expression as a name followed by an open parenthesis. One or
more expressions called arguments may follow the parenthesis;these are used to
pass information to the function for processing.
8
/* Defining and calling a function */
do i = 1 to 5
say i square(i) /* call square */
end
exit /* all done */
square: /* function name */
arg x /* get the "argument" */
return x**2 /* square it and return*/
The function square is defined in the lines followed the label square: up
through the return instruction. Two new instructions are introduced here: arg
retrieves the value of the argument string,and return passes the functon's
result back to the point where the function was called.
One final example will suffice for now. A new instruction called trace is used
here to activate the tracing features of ARexx.
/* Demonstrate "results" tracing */
trace results
sum=0;sumsq=0;
do i = 1 to 5
sum = sum + i
sumsq = sumsq + i**2
end
say 'sum=' sum 'sumsq=' sumsq
When this program is run,the console displays the source lines as they are
excuted,and shows the final results of expressions. This makes it easy to tell
what the program is really doing,and helps reduce the time required to develop
and test a new program. One minor point is illustrated here: the third line
shows two distinct statements separated by a semicolon (;). The semicolon is an
example of a special character,characters that have particular meanings within
ARexx programs.
The following chapters will present further information on the language
statements illustrated here and will introduce others that have not been shown.
Take heart,though;ARexx is a "small" language and there are relatively few
words and rules to learn.
9
THERE WAS NO PAGE 10
ELEMENTS OF THE LANGUAGE
This chapter introduces the rules and concepts that make up the REXX language.
The intent is not to present a formalized definition,but rather to convey a
practical understanding of how the language elements "fit together" to form
programs.
3-1 FORMAT
ARexx programs are compossed of ASCII characters and may be created using any
text editor. No special formatting of the program statements is required or
imposed on the programmer.
3-2 TOKENS
The smallest distinct entities or "words" of the language are called tokens. A
token may be series of characters,as in the symbol MyName,or just a single
character like the "+" operator. Tokens can be categorized into comments,
symbols,strings,operators,and special characters. Each of these groups are
described below.
COMMENT TOKENS
Any group of characters beginning with the sequence "/*" and ending with "*/"
defines a comment token. Comments may be placed anywhere in a program and cost
little in terms of execution speed,since they are stripped(removed)when the
program is first scanned by the interpreter. Comments may be "nested" within
one another,but each "/*" must have a matching "*/" in the program.
Examples:
/* Your basic comment */
/* a /* nested! */ comment */
SYMBOL TOKENS
Any group of the characters a-z,A-Z,0-9,and .!?$_defines a symbol token.
Symbols are translated to uppercase as the program is scanned by the
interpreter,so the symbol MyName is equivalent to MYNAME. Four types of symbols
are recognized:
Fixed symbols begin with a digit (0-9) or a period(.).
Simple symbols do not begin with a digit,and do not contain any
periods.
Stem symbols have exactly one period at the end of the symbol name.
Compound symbols include one or more periods in the interior of the
name.
Stems and compound symbols have special properties that make them useful for
building arrays and lists.
11
SYMBOLS VALUES. The value used for a fixed symbol is always the symbol name
itself(as translated to uppercase.) Simple,stem,and compound symbols are called
variables and may be assigned a value;the value used for an uninitialized
variable is just the variable name itself.
Examples:
123.45 /*a fixed symbol */
MyName /*same as MyName */
a. /*a stem symbol */
a.1.Index /*a compound symbol */
STRING TOKENS
A group of characters beginning and ending with a quote (')or double quote(")
delimiter defines a string token. The delimiter character itself may be
included within the string by a double-delimiter sequence (" or ""). The number
of characters in the string is called its length,and a string of length zero is
called a null string. A string is treated as a literal in an expression;that
is,its value is just the string itself.
Strings followed immediately by an "X" or "B" character that is not part of a
longer symbol are classified as hex or binary strings,respectively,and must be
composed of hexadecimal digits(0-9,A-F) or binary digits(0,1). Blanks are
permitted at byte boundaries for added readability. Hex and binary strings are
convenient for specifying non-ASCII characters and for machine-specific
information like addresses in a program. They are converted immediately to the
"packed" internal form.
Examples:
"Now is the time" /*a simple example */
"" /*a null string */
'Can't you see??' /*Can't you see?? */
'4A 3B CO'X /*a hex string */
'00110111'b /*binary for '7' */
OPERATORS
The characters +-*/=><*| may be combined in the sequences shown in Table 3.1
to form operator tokens. Operator sequences may include leading,trailing,and
embedded blanks,all of which are removed when the program is scanned. In
addition to the above characters,the blank character as a concatenation
operator if it follows a symbol or string and is not adjacent to an operator or
special character.
Each operator has an associated priority that determines the order in which
operations will be performed in an expression. Operators with higher priorities
before those with lower priorities.
12
TABLE 3.1 OPERATOR SEQUENCES
SEQUENCE PRIORITY OPERATOR DEFINITION
8 Logical NOT
+ 8 Prefix Conversion
- 8 Prefix Negation
** 7 Exponentiation
* 6 Multiplication
/ 6 Division
% 6 Integer Division
// 6 Remainder
+ 5 Addition
- 5 Subtration
|| 4 Concatenation
(blank) 4 Blank Concatenation
== 3 Exact Equality
~== 3 Exact Inequality
= 3 Equality
~= 3 Inequality
> 3 Greater Than
>=,~< 3 Greater Than or Equal To
< 3 Less Than
<=,~> 3 Less Than or Equal To
& 2 Logical AND
| 1 Logical Inclusive OR
^,&& 1 Logical Exclusive OR
SPECIAL CHARACTER TOKENS
The characters :():,are each treated as a separate special character token and
have particular meanings within an ARexx program. Blanks adjacent to these
special characters are removed,except for those preceding an open parenthesis
or following a close parenthesis.
COLON (:). A colon,if preceded by a symbol token,defines a label within the
program. Lavels are locations in the program to which control may be
transferred under various conditions.
OPENING AND CLOSING PARENTHESES (()). Parentheses are used in expressions to
group operators and operands into subexpressions,in order to override the
normal operator primorities. An open parenthesis also serves to identify a
function call within an expression;a symbol or string followed immediately by
an open parenthesis defines a function name. Parentheses must always be
balanced within a statement.
SEMICOLON (;). The semicolon acts as a program statement terminator. Several
statements may be placed on a single source line if separated by semicolons.
13
COMMA (,). A comma token acs as the continuation character for statements that
must be entered on several source lines. It is also used to separate the
argument expressions in a function call.
3-3 CLAUSES
Tokens are grouped together to form clauses,the smallest language unit that can
be executed as a statement. Every clause in ARexx can be classified as either a
null,label,assignment,instruction,or command clause. The classification process
is very simple,since no more than two tokens are required to classify any
clause. Assignment,instruction,and command clauses are jointly termed
statements.
CLAUSE CONTINUATION. The end of a source line normally acts as the implicit end
of a clause. A clause can be continued on the next source line by ending the
line with a comma (,). The commas is then removed,and the next line is
considered as a continuation of the clause. There is no limit to the number of
continuations that may occur. String and comment tokens are automatically
continued if a line end before the closing delimiter has been found,and the
"newline" character is not considered to be part of the token.
MULTIPLE CLAUSES. Several clauses can be placed on a single line by separating
them with semicolons(;).
NULL CLAUSES
Lines consisting only of blanks or comments are called null clauses. They have
no function in the execution of a program,except to aid its readability and to
increment the source line count. Null clauses may appear anywhere in a program.
Example:
/* perform annuity calculations */
LABEL CLAUSES
A symbol followed immediately by a colon defines a label clause. A label acts
as a placemarker in the program,but no action occurs with the "execution" of a
label. The colon is considered as an implicit clause terminator,so each label
stands as a separate clause. Label clauses may appear anywhere in a program.
Examples:
start: /* begin execution */
syntax: /* error processing */
ASSIGNMENT CLAUSES
Assignments are identified by a variable symbol followed by an "=" operator. In
this context the operator's normal definition(an equality comparison)is
overridden,and it becomes an assignment operator. The tokens to the right of
the "=" are evaluated as an expression,and the result is assigned to(becomes
the value of)the variable symbol.
14
Examples:
when= 'Now is the time'
answ= 3.14 * fact(5)
INSTRUCTION CLAUSES
Instructions begin with certain keyword symbols,each of which denotes a
particular action to be performed. Instruction keywords are recognized as such
only at the beginning of a clause,and may otherwise be used freely as symbols
(although such use may become confusing at times.) The ARexx instructions are
described in detail in Chapter 4.
Examples:
drop a b c /* reset variables */
say 'please' /* a polite program */
if j > 5 then leave; /* several instructions */
COMMAND CLAUSES
Commands are any ARexx expression that can't be classified as one of the
preceding types of clauses. The expression is evaluated and the result is
issued as a command to an external host,which might be the native operating
system or an application program. Commands are discussed in Chapter 5,and the
details of the host command interface are given in Chapter 10.
Examples:
'delete' 'myfile' /* a DOS command */
'jump' current+10 /* an editor command? */
CLAUSE CLASSIFICATION
The process by which program lines are divided into clauses and then classified
is important in understanding the operation of an ARexx program. The language
interpreter splits the program source into groups of clauses as the program is
read,using the end of each line as a clause separator and applying the
continuation rule as required. These groups of one or more clauses are then
tokenized,and each clause is classified into one of the above types. Note that
seemingly small syntactic differences may completely change the semantic
content of a statement. For example,
SAY 'Hello, Bill'
is an instruction clause and will display "Hello, Bill" on the console,but
""SAY 'Hello, Bill'
is a command clause,and will issue "SAY Hello, Bill" as a command to an
external program. The presence of the leading null string changes the
classification from an instruction clause to a command clause.
15
3-4 EXPRESSIONS
Expression evaluation is an important part of ARexx programs,since most
statements include at least one expression. Expressions are composed of
strings,symbols,operators,and parentheses. Strings are used as literals in an
expression;their value in an operation is just the string itself. Fixed symbols
are also literals(remember that symbols are always translated to uppercase,)
but variable symbols may have an assigned value. Operator tokens represent the
predefined operations of ARexx;each operator has an associated priority that
determines the order in which operations will be performed. Parentheses may be
used to alter the normal order of evaluation in the expression,or to identify
function calls. A symbol or string followed immediately by an open parenthesis
defines the function name,and the tokens between the opening and(final)closing
parenthesis form the argument list for the function.
For example,the expression "J 'fractorial is' fact(J)" is composed of a symbol
J,a blank operator,the string 'factorial is',another blank,the symbol fact,an
open parenthesis,the symbol J again,and a closing parenthesis. FACT is a
function name and (J) is its argument list,in this case the single expression
J.
SYMBOL RESOLUTION
Before the evaluation of an expression can proceed,the interpreter must obtain
a value for each symbol in the expression. For fixed symbols the value is just
the symbol name itself,but variable symbols must be looked up in the current
symbol table. In the example above,the expression after symbol resolution would
be "3 'factorial is' FACT(3)," assuming that the symbol J had the value 3.
Suppose that the example above had been "FACT(J) 'is' J 'factorial'." Would the
second occurrence of symbol J still resolve to 3 in this case? In general,
function calls may have "side effects" that include altering the values of
variables,so the value of J might have been changed by the call to FACT. In
order to avoid ambiguities in the values assigned to symbols during the
resolution process, ARexx guarantees a strict left-to-right resolution order.
Symbol resolution proceeds irrespective of operator priority or parenthetical
grouping;if a function call is found,the resolution is suspended while the
function is evaluated. Note that it is possible for the same symbol to have
more than one value in an expression.
ORDER OF EVALUATION
After all symbol values have been resolved,the expression is evaluated based on
operator priority and subexpression grouping. Operators of higher priority are
evaluated first. ARexx does not guarantee an order of evaluation among
operators of equal priority,and does not employ a "fast path" evaluation of
boolean operators. For example,in the expression
(1 = 2) & (FACT(3) = 6)
the call to the FACT function will be made,although it is clear that the final
result will be 0,since the first term of the AND operation is 0.
16
3-5 NUMBERS AND NUMERIC PRECISION
An important class of operands are those representing numbers. Numbers consist
of the characters 0-9,.+-,and blanks;an e or E may follow a number to indicate
exponential notation,in which case it must be followed by a (signed) integer).
Both string tokens and symbol tokens may be used to specify numbers. Since the
language is typeless,variables do not have to be declared as "numeric" before
being used in an arithmetic operation. Instead,each value string is examined
when it is used to verify that it represents a number. The following examples
are all valid numbers:
33
" 12.3 "
0.321e12
' + 15.'
Note that leading and trailing blanks are permitted,and that blanks may be
embedded between a "+" or "-" sign and the number body(but not within the
body.)
BOOLEAN VALUES
The numbers 0 and 1 are used to represent the boolean values False and True,
respectively. The use of a value other than 0 or 1 when a boolean operand is
expected will generate an error. Any number equivalent to 0 or 1,for example
"0.000" or "0.1E1," is also acceptable as a boolean value.
NUMERIC PRECISION
ARexx allows the basic precision used for arithmetic calculations to be
modified while a program is executing. The number of significant figures used
in arithmetic operations is determined by the Numeric Digits environment
variable, and may be modified using the NUMERIC instruction.
The number of decimal places used for a result depends on the operation
performed and the number of decimal places in the operands. Unlike many
languages,ARexx preserves trailing zeroes to indicate the precision of the
result. If the total number of digits required to express a value exceeds the
current Numeric Digits setting,the number is formatted in exponential notation.
Two such formats are provided:
In SCIENTIFIC notation,the exponent is adjusted so that a single digit is
placed to the left of the decimal point.
in ENGINEERING notation,the number is scaled so that the exponent is a multiple
of 3 and the digits to the left of the decimal point range from 1 to 999.
The numeric precision and format can be set using the NUMERIC instruction.
17
3-6 OPERATORS
Operators can be grouped into four categories:
Arithmetic operators require one or two numeric operands,and produce a numeric
result.
Concatenation operators join two strings into a single string.
Comparison operators require two operands,and produce a boolean(0 or 1) result.
Logical Operators require one or two boolean operands,and produce a boolean
result.
ARITHMETIC OPERATORS
The aritmetic operators are listed in Table 3.2 below. Note the inclusion of
the integer division(%)and remainder(//)operators,along with the usual
arithmetic operations. The result of an arithmetic operation is always foratted
based on the current Numeric Digits setting,and will never have leading or
trailing blanks.
TABLE 3.2 ARITHMETIC OPERATORS
SEQUENCE PRIORITY OPERATION
+ 8 Prefix Conversion
- 8 Prefix Negation
** 7 Exponentiation
* 6 Multiplication
/ 6 Division
% 6 Integer Division
// 6 Remainder
+ 5 Addition
- 5 Subtraction
PREFIX CONVERSION(+). This unary operator converts the operand to and internal
numeric form and formats the result based on the current Numeric Digits
settings. This causes any leading and trailing blanks to be removed,and may
result in a loss of precision.
Examples:
' 3.12 ' ==> 3.12
1.5001 ==> 1.500 /* If digits = 3 */
PREFIX NEGATION(-). This unary operator negates the operand. The result is
formatted based on the current Numeric Digits setting.
18
Examples:
-' 3.12 ' ==> -3.12
1.5E2 ==>-150
EXPONENTIATION(**). The left operand is raised to the power specified by the
right operand,which must be an integer. The number of decimal places for the
result is the product of the exponent and the number of decimal places in the
base.
Examples:
2**3 ==>8
3**-1 ==>.333333333
0.5**3 ==>0.125
MULTIPLICATION(*). The product of two numbers is computed. The number of
decimal places for the result is the sum of the decimal places of the operands.
Examples:
12 * 3 ==>36
1.5 * 1.50 ==>2.250
DIVISION(/). The quotient of two numbers is computed. The number of decimal
places for the result depends on the current setting of the numeric DIGITS
variable;the nuber is formatted to the maximum precision required.
Examples:
6 / 3 ==>2
8 / 3 ==>2.66666667
INTEGER DIVISION(%). The quotient of two numbers is computed,and the integer
part of the quotient is used as the result.
Examples:
5 % 3 ==>1
-8 % 3 ==>-2
REMAINDER(//). The result is the remainder after the two operands are divided.
The remainder for "a//b" is calculated as "a-(a%b)*b." If both operands are
positive integers,this operation yields the usual "modulo" result.
19
Examples:
5 // 3 ==>2
-5 // 3 ==>-2
5.1 // 0.2 ==>0.1
ADDITION(+). The sum of two numbers is computed. The number of decimal places
for the result is the larger of the decimal places of the operands.
Examples:
12 + 3 ==>15
3.1 + 4.05 ==>7.15
SUBTRATION(-). The difference of two numbers is computed. As in the case of
addition,the number of decimals places for the result is the larger of the
decimal places of the operands.
Examples:
12 - 3 ==>9
5.55 - 1.55 ==>4.00
CONCATENATION OPERATORS
ARexx defines two concatenation operators,both of which require two operands.
The first,identified by the operator sequence "||",joins two strings into a
single string with no intervening blank. The second concatenation operation is
identified by the blank operator,and joins the two operand strings with one
intervening blank.
An implicit concatenation operator is recognized when a symbol and a string are
directly abutted in an expression. Concatenation by abuttal uses the "||"
operator,and behaves exactly as though the operator had been provided
explicitly.
Examples:
'why me,' || 'Mom?' ==>why me,Mom?
'good' 'times' ==>good times
one'two'three ==>ONEtwoTHREE
COMPARISON OPERATORS
Comparisons are performed in one of three modes,and always result in a boolean
value(0 or 1.)
Exact comparisons proceed character-by-character,including any leading blanks
that may be present.
String comparisons ignore leading blanks,and pad the shorter string with blanks
if necessary.
20
Numeric comparisons first convert the operands to an internal numeric form
using the current Numeric Digits setting,and then perform a standard arithmetic
comparison.
Except for the exact equality and exact inequality operators,all comparison
operators dynamically determine whether a string of numeric comparison is to be
performed. A numeric comparison is performed if both operands are valid numbers
otherwise,the operands are compared as strings.
TABLE 3.3 COMPARISON OPERATORS
SEQUENCE PRIORITY OPERATION MODE
== 3 Exact Equality Exact
~== 3 Exact Inequality Exact
= 3 Equality String/Numeric
~= 3 Inequality String/Numeric
> 3 Greater Than String/Numeric
>=,~< 3 Greater Than or Equal String/Numeric
< 3 Less Than String/Numeric
<=,~> 3 Less Than or Equal String/Numeric
LOGICAL (BOOLEAN) OPERATORS
ARexx defines the four logical operations NOT,AND,OR,and Exclusive OR,all of
which require boolean operands and produce a boolean result. Boolean operands
must have values of either 0(False)or 1(True.) An attempt to perform a logical
operation on a non-boolean operand will generate an error.
TABLE 3.4 LOGICAL OPERATORS
SEQUENCE PRIORITY OPERATION
~ 8 NOT(Inversion)
& 2 AND
| 1 OR
^,&& 1 Exclusive OR
3-7 STEMS AND COMPOUND SYMBOLS
Stems and compound symbols have special properties that allow for some
interesting and unusual programming. A compound symbol can be regarded as
having the structure stem.n1.n2.n3...nk where the leading name is a stem symbol
and each node n1...nk is a fixed or simple symbol. Whenever a compound symbol
appears in a program,its name is expanded by replacing each node with its
current value as a (simple) symbol. The value string may consist of any
characters,including embedded blanks,and is not converted to uppercase. The
result of the expansion is a new name that is used in place of the compound
symbol. For example if j has the value of 3 and k has the value 7,then the
compound symbol a.j.k will expand to A.3.7.
Stem symbols provide a way to initialize a whole class of compound symbols.
When an assignment is made to a stem symbol,it assigns that value to all
possible compound symbols derived from the stem. Thus,the value of a compound
symbol depends on the prior assignments made to itself or its associated stem.
21
Compound symbols can be regarded as a form of "associative" or "content-
addressable" memory. For example,suppose that you needed to store and retrieve
a set of names and telephone numbers. The conventional approach would be to set
up two arrays NAME and NUMBER,each indexed by an integer running from one to
the number of entries. A number would be "looked up" by scanning the name array
until the given name was found,say in NAME.12,and then retrieving NUMBER.12.
With compound symbols,the symbol NAME could hold the name to be looked-up,and
NUMBER.NAME would then expand to NUMBER.Bill(for example),which be the
corresponding number.
Of course,compound symbols can also be used as conventional indexed arrays,with
the added convenience that only a single assignment(to the stem)is required to
initialize the entire array.
3-8 THE EXECUTION ENVIRONMENT
The ARexx interpreter provides a uniform environment by running each program as
a separate task(actually,as a DOS process)in the Amiga's multitasking operating
system. This allows for a flexible interface between an external host program
and the interpreter,as the host can either proceed concurrently with its
operations or can simply wait for the interpreted program to finish.
THE EXTERNAL ENVIRONMENT
The external environment of a program includes its task(process)structure,
input and output streams,and current directory. When each ARexx task is
created,it inherits the input and output streams and current directory from its
client,the external program that invoked the ARexx program. The current
directory is used as the starting point in a search for a program or data file.
EXTERNAL PROGRAMS. The external environment usually includes one or more
external programs with which the ARexx program may communicate. Any program
that supports a suitable interface can receive commands from ARexx programs.
The command interface is discussed in Chapter 5.
THE INTERNAL ENVIRONMENT
The internal environment of an ARexx program consists of a static global
structure and one or more storage environments. The global data values are
fixed at a time the program is invoked,and include the argument strings,program
source code,and static data strings. The storage environment includes the
symbol table used for variable values,the numeric options,trace options,and
host address strings. While the global environment is unique,there may be many
storage environments during the course of the program execution. Each time an
internal function is called a new storage environment is activated and
initialized. The initial values for most fields are inherited from the previous
environment,but values may be changed afterwards without affecting the caller's
environment. The new environment persists until control returns from the
function.
22
ARGUMENT STRINGS. A program may receive one or more argument strings when it is
first invoked. These arguments persist for the duration of the program and are
never altered. The number of arguments a program receives depends in part on
the mode of invocation. ARexx programs invoked as commands normally have only
one argument string,although the "command tokenization" option may provide more
than one. A program invoked as a function can have any number of arguments if
called as an internal function,but external functions are limited to a maximum
of 15 arguments.
The argument strings can be retrieved using either the ARG instruction or the
ARG() Built-In function. ARG() can also return the total number of arguments,or
the status(as "exists" or "omitted")of a particular argument.
THE SYMBOL TABLE. Every storage environment includes a symbol table to store
the value strings that have been assigned to variables. This symbol table is
organized as a two-level stores entries for simple and stem symbols,and the
secondary level is used for compound symbols. All of the compound symbols
associated with a particular stem are stored in one tree,with the root of the
tree held by the entry for the stem.
Symbols are not entered into the table until an assignment is made to the
symbol. Once created,entries at the primary level are never removed,even if the
symbol subsequently becomes uninitialized. Secondary trees are released
whenever an assignment is made to the stem associated with the tree.
For the most part ARexx programmers need not be concerned with the details of
storage environments except to understand what values are saved when a function
is called. Applications developers who need to manipulate environment values
should refer to the structure definitions in the INCLUDE files provided on the
ARexx distribution disk.
INPUT AND OUTPUT
Most computer programs require some means of communicating with the outside
world,either to accept input data or to pass along results. The REXX language
includes only a minimal specification of input and output (I/O)operations,
leaving the choice of additional functionality to the language implementor.
This is in keeping with the design of many computer languages. For instance,the
"C" language has no statements dedicated to I/O,but instead relies on a
standardized set of I/O functions.
ARexx extends the I/O facilities fo REXX by providing Built-In functions to
manipulate external files. Files are referenced by a logical name associated
with the file when it is first opened. The initial input and output streams are
given the names STDIN and STDOUT.
ARexx maintains a list of all of the files opened by a program and
automatically closes them when the program finishes. There is no limit to the
number of files that may be open simultaneously.
23
RESOURCE TRACKING
ARexx provides complete tracking for all of the dynamically-allocated resources
that it uses to execute a program. These resources include memory space,DOS
files and related structures,and the message port structures supported by
ARexx. The tracking system was designed to allow a program to "bail out" at any
point(perhaps due to an execution error)without leaving any hanging resources.
It is possible to go outside of the interpreter's resource tracking net by
making calls directly to the Amiga's operating system from within an ARexx
program. In these cases it is the programer's responsibility to track and
return all of the allocated resources. ARexx provides a special interrupt
facility so that a program can retain control after an execution error,perform
the required cleanup,and then make an orderly exit. Chapter 7 has information
on the ARexx interrupt system.
24
CHAPTER 4 INSTRUCTIONS
Instruction clauses are identified by an initial keyword symbol that is not
followed by a colon(:)or an equals(=)operator. Each instruction signifies a
specific action,and may be followed by one or more subkeywords,expressions,or
other instruction-specific information. Instruction keywords and subkeywords
are recognized only in this specific context,and are therefore not "reserved
words" in the usual sense of the term. Keywords may be used freely as variables
or function names,although such usage may become confusing at times.
In the descriptions that follow,keywords are shown in uppercase and optional
parts of the instruction are enclosed in brackets. Alternative selections are
separated by a vertical bar(|),and required alternative are enclosed in braces
({}).
4-1 ADDRESS
Usage: ADDRESS [Symbol|string|VALUE] [expression]]
This instruction specifies a host address for commands issued by the
interpreter. A host address is the name associated with an external program to
which commands can be sent;external hosts are described in Chapter 5. ARexx
maintains two host addresses:a "current" and a "previous"address is lost,and
the "current" and a "previous" value. Whenever a new host address is supplied,
the "previous" address is lost,and the "current" address becomes the "previous"
one. These host addresses are part of a program's storage environment and are
preserved across internal function calls. The current address can be retrieved
with the Built-In function ADDRESS(). There are four distinct forms for the
ADDRESS instruction:
ADDRESS {string | symbol} expression. The expression is evaluated and the
result is issued to the host specified by the string or symbol,which is taken
as a literal. No changes are made to the current or previous address strings.
This provides a convenient way to issue a single command to an external host
without disturbing the current host addresses. The return code from the command
is treated as it would be from a command clause.
ADDRESS {string | symbol}. The string or symbol,taken as a literal,specifies
the new host address. The current host address becomes the previous address.
ADDRESS [VALUE] expression. The result of the expression specifies the new host
address,and the current address becomes the previous address. The VALUE keyword
may be omitted if the first token of the expression is not a symbol or string.
ADDRESS. This form interchanges the current and previous hosts. Repeated
execution will therefore "toggle" between the two host addresses.
Examples:
address edit /* set an new host address */
address edit 'top' /* move to the top */
address VALUE edit n /* compute a new host address */
address /* swap current and previous */
25
Usage: ARG [template] [,template...]
ARG is shorthand form for the PARSE UPPER ARG instruction. It retrieves one or
more of the argument strings available to the program,and assigns values to the
variables in the template. The number of argument strings available depends on
the whether the program was invoked as a command or a function. Command
invocations normally have only one argument string,but functions may have up to
15. The argument strings are not altered by the ARG instruction.
The structure and processing of templates is described briefly with the PARSE
instruction,and in greater depth in Chapter 8.
Example:
arg first,second /* fetch arguments */
4-3 BREAK
Usuage: BREAK
The BREAK instruction is used to exit from the range of a DO instruction or
from within an INTERPRETed string,and is valid only in these contexts. If used
within a DO statement,BREAK exits from the innermost DO statement containing
the BREAK. This contrasts with the otherwise similar LEAVE instruction,which
exits only from an interative DO.
Example:
do /* begin block */
if i>3 then break /* all done? */
a = a + 1
y.a = name
end /* end block */
4-4 CALL
Usage: CALL {symbol | string} [expression] [,expression,...]
The CALL instruction is used to invoke an internal or external function. The
function name is specified by the symbol or string token,which is taken as a
literal. Any expressions that follow are evaluated and become the arguments to
the called function. The value returned by the function is assigned to the
special variable RESULT. It is not an error if a result string is not returned;
in this case the variable RESULT is DROPed(becomes uninitialized.)
The linkage to the function is established dynamically at the time of the call.
ARexx follows a specific search order in attempting to locate the called
function;this process is described in Chapter 6.
Example:
call center name,length+4,'+'
26
Usage: DO [var=exp] [To exp] [BY exp]] [FOR exp] [FOREVER] [WHILE exp | UNTIL
exp]
The DO instruction begins a group of instructions to be executed as a block.
The range of the DO instruction includes all statements up to and including an
eventual END instruction. There are two basic forms of the instruction:
The DO keyword by itself defines a block of instructions to be executed once.
If any iteration specifiers follow the DO keyword,the block of instructions is
executed repeatedly until a termination condition occurs.
An interative DO instruction is sometimes called a "loop",since the interpreter
"loops back" to perform the instruction repeatedly. The various parts of the DO
instruction are described below.
Initializer expression. An initializer expression of the form "variable=
expression" defines the index variable of the loop. The expression is evaluated
when the DO range is first activated,and the result is assigned to the index
variable. On subsequent iterations an expression of the form "variable =
variable + increment" is evaluated,where the increment is the result of the BY
expression. If specified, the initializer expression must precede any of the
other subkeywords.
BY expression. The expression following a BY symbol defines the increment to be
added to the index variable in each subsequent iteration. The expression must
yield a numeric result,which may be positive or negative and need not be an
integer. The default increment is 1.
TO expression. The result of the TO expression specifies the upper(or lower)
limit for the index variable. At each iteration the index variable is compared
to the TO result. If the increment(BY result)is positive and the variable is
greater than the limit,the DO instruction terminates and control passes to the
statement following the END instruction. Similarly,the loop terminates if the
increment is negative and the index variable is less than the limit.
FOR expression. The FOR expression must yield a positive whole number when
evaluated,and specifies the maximum number of iterations to be performed. The
loop terminates when this limit is reached irrespective of the value of the
index variable.
FOREVER. The FOREVER keyword can be used if an iterative DO instruction is
required but no index variable is necessary. Presumably the loop will be
terminated by a LEAVE or BREAK instruction contained within the loop body.
WHILE expression. The WHILE expression is evaluated at the beginning of each
iteration and must result in a boolean value. The iteration proceeds if the
result is 1;otherwise,the loop terminates.
27
UNTIL expression. The UNTIL expression is evaluated at the end of each
iteration and must result in a boolean value. The instruction continues with
the next iteration if the result is 0,and terminates otherwise.
The initializer,BY,TO,and FOR expressions are evaluated only when the
instruction is first activated,so the increment and limits are fixed throughout
the execution. Note that a limit need not be supplied;for example,the
instruction "DO i=1" will simply count away forever. Note also that only one of
the WHILE or UNTIL keywords can be specified.
Example:
do i=1 to limit for 5 while time <50
y.1=i*time
end
4-6 DROP
Usage: DROP variable [variable...]
The specified variable symbols are reset to their uninitialized state,in which
the value of the variable is the variable name itself. It is not an error to
DROP a variable that is already uninitialized. DROPping a stem symbol is
equivalent to DROPping the values of all possible compound symbols derived from
that stem.
Example:
a=123 /* assign a value */
drop a b /* drop some */
say a b /* ==>A B */
4-7 ECHO
Usage: ECHO [expression]
The ECHO instruction is a synonym for the SAY instruction. It displays the
expression result on the console.
Example:
echo "You don't SAY!"
4-8 ELSE
Usage: ELSE [;] [conditional statement]
The ELSE instruction provides the alternative conditional branch for an IF
statement. It is valid only within the range of an IF instruction,and must
follow the conditional statement of the THEN branch. If the THEN branch wasn't
executed,the statement following the ELSE clause is performed.
Binding. ELSE clauses always bind to the nearest(preceding)IF statement. It may
be necessary to provide "dummy" ELSE clauses for the inner IF ranges of a
compound IF statement in order to allow alternative branches for the outer IF
statements. In this case it is not sufficient to follow the else with a
semicolon or a null clause. Instead,the NOP(no-operation)instruction can be
used for this purpose.
28
Example:
if 1 > 2 then say 'really?'
else say 'I thought so'
4-9 END
Usage: END [variable]
The END instruction terminates the range of a DO or SELECT instruction. If the
optional variable symbol is supplied,it is compared to the index variable of
the DO statement(which must therefore be iterative). An error is generated if
the symbols do not match,so this provides a simple mechanism for matching the
DO and END statements.
Example:
do i=1 to 5 /* index variable is I */
say i
end i /* end "I" loop */
4-10 EXIT
Usage: EXIT [expression]
The EXIT instruction terminates the execution of a program,and is valid
anywhere within a program. The evaluated expression is passed back to the
caller as the function or command result.
Results Processing. The processing of the EXIT result depends on whether a
result string was requested by the calling program,and whether the current
invocation resulted from a command or function call. If a result string was
requested,the expression result is copied to a block of allocated memory and a
pointer to the block is returned as the secondary result of the call.
If the caller did not request a result string,and the program was invoked as a
command,then an attempt is made to convert the expression result to an
integer. This value is then returned as the primary result,with 0 as the
secondary result. This allows the EXIT expression to be interpreted as a
"return code" by the caller. Refer to Chapter 10 for further information on
the data structures used to return the result string.
Examples:
exit /* no result needed */
exit 12 /* an error return? */
4-11 IF
Usage: IF expression [THEN] [;] [conditional statement]
The IF instruction is used in conjunction with THEN and ELSE instruction to
conditionally execute a statement. The result of the expression must be a
boolean value. If the result is 1 (True),the statement following the THEN
symbol is executed;otherwise,control passes to the next statement(which might
be an ELSE clause.) The THEN keyword need not immediately follow the IF
expression,but may appear as a separate clause. The instruction
29
is actually analyzed as "IF expression; THEN; statement;." In essence,the IF
statement begins a syntactic range and establishes the test condition that
determines whether subsequent THEN or ELSE clauses will be performed.
Any valid statement may follow the THEN symbol;in particular,a "DO; ... END;"
group allows a series of statements to be performed conditionally.
Examples:
if result < 0 then exit /* all done? */
4-12 INTERPRET
Usage: INTERPRET expression
The expression is evaluated and the result is executed as one or more program
statements. The statements are considered as a group,as though surrounded by a
"DO; ...;END" combination. Any statements can be included in the INTERPRETed
source,including DO or SELECT instruction.
An INTERPRET instruction activates a control range when it is executed,which
serves as a "fence" for LEAVE and ITERATE instructions. These instructions can
therefore be used only with DO-loops defined within the INTERPRET. The BREAK
instuction can be used to terminate the processing of INTERPRETed statements.
While it is not an error to include label clauses within the interpreted
string,only those labels defined in the original source code are searched
during a transfer of control.
The INTERPRET instruction can be used to solve programming problems in
interesting and novel ways. Programs can be constructed dynamically and then
executed using this instruction,or program fragments may be passed as arguments
to functions,which then INTERPRET them.
Example:
inst = 'say' /* an instruction */
interpret inst hello /* ..."say HELLO" */
4-13 ITERATE
Usage: ITERATE [variable]
The ITERATE instruction terminates the current iteration of a DO instruction
and begins the next iteration. Effectively,control passes to the END statement
and then(depending on the outcome of the UNTIL expression)back to the DO
statement. The instruction normally acts on the innermost iterative DO range
containing the instruction. An error results if the LEAVE instruction is not
contained within an iterative DO instruction.
The optional variable symbol specifies which DO range is to be exited,in the
event that several nested ranges exist. The variable is taken as a literal and
must match the index variable of a currently active DO instruction. An error
results if no such matching DO instruction is found.
30
Example:
do i=1 to 3
if i=j then iterate i
end
4-14 LEAVE
Usage:LEAVE [variable]
LEAVE forces an immediate exit from the iterative DO range containing the
instruction. An error results if the LEAVE instruction is not contained within
an iterative DO instruction.
The optional variable symbol specifies which DO range is to be exited,in the
event that several nested ranges exist. The variable is taken as a literal and
must match the index variable of a currently active DO instruction. An error
results if no such matching DO instruction is found.
Example:
do i=1 to limit
if i > 5 then leave /* maximum iterations */
end
4-15 NOP
Usage: NOP
The NOP or "no-operation" instruction does just that:nothing. It is provided to
control the binding of ELSE clauses in compound IF statements.
Example:
if i=j then /* first (outer) IF */
if j=k then a=o /* inner IF */
else nop /* binds to inner IF */
else a=a+1 /* binds to outer IF */
4-16 NUMERIC
Usage: NUMERIC {DIGITS | FUZZ} expression
or: NUMERIC FORM {SCIENTIFIC | ENGINEERING}
This instruction sets options relating to the numeric precision and format. The
valid forms of the NUMERIC instruction are:
NUMERIC DIGITS expression. Specifies the number of digits of precision for
arithmetic calculations. The expression must evaluate to a positive whole
number.
NUMERIC FUZZ expression. Specifies the number of digits to be ignored in
numeric comparison operations. This must be a positive whole number that is
less than the current DIGITS setting.
NUMERIC FORM SCIENTIFIC. Specifies that numbers that require exponential
notation be expressed in SCIENTIFIC notation. The exponent is adjusted so that
the mantissa (for non-zero) numbers) is between 1 and 10. This is the default
format.
31
NUMERIC FORM ENGINEERING. Selects ENGINEERING format for numbers that require
exponential notation. ENGINEERING format normalizes a number so that its
exponent is a multiple of three and the mantissa(if not 0)is between 1 and
1000.
The numberic options are preserved when an internal function is called.
Examples:
numeric digits 12 /* precision */
numeric form scientific /* format */
4-17 OPTIONS
Usage: OPTIONS [FAILAT expression]
or: OPTIONS [PROMPT expression]
or: OPTIONS [RESULTS]
The OPTIONS instruction is used to set various internal defaults. The FAILAT
expression sets the limit at or above which command return codes will be
signalled as errors,and must evaluate to an integer value. The PROMPT
expression provides a string to be used as the prompt with the PULL (or PARSE
PULL)instruction. The RESULTS keyword indicates that the interpreter should
request a result string when it issues commands to an external host.
The internal options controlled by this instruction are preserved across
function calls,so an OPTIONS instruction can be issued within an internal
function without affecting the callers environment. If no keyword is specified
with the OPTIONS instuction,all controlled options revert to their default
settings.
Example:
options failat 10
options prompt "Yes Boss?"
options results
4-18 OTHERWISE
Usage: OTHERWISE [;] [conditional statement]
This instruction is valid only within the range of a SELECT instruction,and
must follow the "WHEN ... THEN" statements. If none of the preceding WHEN
clauses have succeeded,the statement following the OTHERWISE instruction is
executed. An OTHERWISE is not mandatory within a SELECT range. However,an error
will result if the OTHERWISE clause is omitted and none of the WHEN
instructions succeed.
Example:
select
when i=1 then say 'one'
when i=2 then say 'two'
otherwise say 'other'
end
32
4-19 PARSE
Usage: PARSE [UPPER] inputsorce [template] [,template...]
The PARSE instruction provides a mechanism to extract one or more substrings
from a string and assign them to variables. The input string can come from a
variety of sources,including argument strings,an expression,or from the
console. The template provides both the variables to be given values and the
way to determine the value strings. The template may be omitted if the
instruction is intended only to create the input string. The different options
of the instruction are described below.
INPUT SOURCES
The sources for the input strings are specified by the keyword symbols listed
below. When multiple templates are supplied,each template receives a new input
string, although for some source options the new string will be identical to
the previous one. The input source string is copied before being parsed,so the
original strings are never altered by the parsing process.
UPPER. This optional keyword may be used with any of the input sources,and
specifies that the input string is to be translated to uppercase before being
parsed. It must be the first token following PARSE.
ARG. This input option retrieves the argument strings supplied when the program
was invoked. Command invocations normally have only a single argument string,
but functions may have up to 15 argument strings. Multiple templates may be
given to retrieve successive argument strings.
EXTERNAL. The input strings is read from the console. If multiple templates are
supplied,each template will read a new string. This source option is the same
as PULL.
NUMERIC. The current numeric options are placed in a string in the order
DIGITS,FUZZ,and FORM,separated by a single space.
PULL. Reads a string from the input console. If multiple templates are
supplied,each template will read a new string.
SOURCE. The "source" string for the program is retrieved. This string is
formatted as "{COMMAND | FUNCTION} {0 | 1} called resolved ext host." The first
token indicates whether the program was invoked as a command or as a function.
The second token is a boolean flag indicating whether a result string was
requested by the caller. The called token is the name used to invoke this
program,while the resolved token is the final resolved name of the program. The
ext token is the file extension to be used for searching(the default is
"REXX"). Finally,the host token is the initial host address for commands.
VALUE expression WITH. The input string is the result of the supplied
expression. The WITH keyword is required to separate the expression from the
template. The expression result may be parsed repeatedly by using multiple
templates,but the expression is not reevaluated.
VAR variable. The value of the specified variable is used as the input string.
When multiple templates are provided,each template uses the current value of
the variable.
33
This value may change if the variable is included as an assignment target in
any of the templates.
VERSION. The current configuation of the ARexx interpreter is supplied in the
form "ARexx version cpu mpu video freq". The version toekn is the release level
of the interpreter,formatted as V1.0. The cpu token indicates the processor
currently running the program,and will be one of the values 68000,68010,or
68020. The mpu token will be either NONE or 68881 depending on whether a math
coprocessor is available on the system. The video token will indicate either
NTSC or PAL,and the freq token gives the clock(line)frequency as either 60HZ or
50 HZ.
TEMPLATES
Parsing is controlled by a template,which may consist of symbols,strings,
operators,and parentheses. During the parsing operation the input string is
split into substrings that are assigned to the variable symbols in the
template. The process continues until all of the variables in the template have
been assigned a value;if the input string is "used up",any remaining variables
are given null values.
Templates are described in depth in Chapter 8,so only a simplified description
is presented here. The goal of the parsing operation is to associate a
"current" and "next" position with each variable symbol in the template. The
substring between these positions is then assigned as the value to the
variable. There are three basic methods used to determine the value strings.
PARSING BY TOKENIZATION. When a variable in the template is followed
immediately by another variable,the value string is determined by breaking the
input string into words separated by blanks. Each word is assigned to a
variable in the template.
Values determined by tokenization will never have leading or trailing blanks.
Normally the last variable in the template receives the untokenized remainder
of the input string,since it is not followed by a symbol. A "placeholder"
symbol,signified by a period(.),may be used to force tokenization. Placeholders
behave like variables in the template except that they are never actually
assigned a value.
Example:
/* Numeric string is: "9 0 SCIENTIFIC" */
parse numberic digits fuzz form .
say digits /* =>9 */
say fuzz /* =>0 */
say from /*=> SCEIENTIFIC */
PARSING BY POSITION. If the fields in the input string have known positions,
value strings can be specified by absolute or relative positions. Relative
positions are indicated by a number preceded by a "+" or "-" operator. Each
positional marker updates the scan position in the string. The value assigned
to a variable is the string from the current position up to,but not including,
the next position in the string.
34
Example:
/* assume argument is "1234567890" */
parse arg 1 a 3 b +2 1 c
say a b c /* ==> 12 34 1234567890 */
PARSING WITH PATTERNS. Fields in the input string separated by specific
characters or strings can be parsed using a pattern,which is matched against
the input string. A pattern is specified in the template as a string token,or
alternatively as a symbol enclosed in parentheses. The position in the parse
string matched by the pattern determines the value strings. The pattern is
removed from the input string when a match is found;this is the only parsing
operation that modifies the input string.
Example:
check = 'one,two,three'
parse var check a ',' b ',' c
say a b c /* ==> one two three */
4-20 PROCEDURE
Usage:PROCEDURE [EXPOSE variable [variable...]]
The PROCEDURE instruction is used within an internal function to create a new
symbol table. This protects the symbols defined in the caller's environment
from being altered by the execution of the function. PROCEDURE is usually the
first statement within the function,although it is valid anywhere withing the
function body. It is an error to execute two PROCEDURE statements within the
function.
EXPOSING VARIABLES. The EXPOSE subkeyword provides a selective mechanism for
accessing the caller's symbol table,and for passing global variables to a
function. The variables following the EXPOSE keyword are taken to refer to
symbols in the caller's table. Any subsequent changes made to these variables
will be reflected in the caller's environment.
The variables in the EXPOSE list may include stems or compound symbols,in which
case the ordering of the variables becomes significant. The EXPOSE list is
processed from left to right,and compound symbols are expanded based on the
values in effect in the new generation. For example,suppose that the value of
the symbol J in the previous gneration is 123,and that J is unitialized in the
new generation. Then PROCEDURE EXPOSE J A.J will expose J and A.123,whereas
PROCEDURE EXPOSE A.J J will expose A. J. and J. Exposing a stem has the effect
of exposing all possible compound symbols derived from that stem.
Example:
fact: procedure /* a recursive function */
arg i
if i <=1
then return 1
else return i*fact(i-1)
35
Usage:PULL [template] [,template...]
This is a shorthand form of the PARSE UPPER PULL instruction. It reads a string
from the input console,translates it to uppercase,and parses it using the
template. Multiple strings can be ready by supplying additional templates. The
instruction will read from the console even if no template is given.
Templates are described briefly with the PARSE instruction and in greater depth
in Chapter 8.
Example:
pull first last. /* read names */
4-22 PUSH
Usage: PUSH [expression]
The PUSH instruction is used to prepare a stream of data to be ready by a
command shell or other program. It appends a "newline" to the result of the
expression and then stacks or "pushes" it into the STDIN stream. Stacked lines
are placed in the stream in "last-in, first-out" order,and are then available
to be ready just as though they had been entered interactively. For example,
after issuing the instructions
push line 1
push line 2
push line 3
the steam would be read in the order "line 3," "line 2" and "line 1."
There are several restrictions governing the use of the PUSH instruction and
its alter ego QUEUE. These instructions use a special I/O mechanism to
accomplish their task,and as a result can be used only with an interactive
(stream-model) I/O device like a console or pipe. The stream must be managed by
with a DOS handler that supports the special ACTION_STACK (for PUSH) or
ACTION_QUEUE (for QUEUE) command.
PUSH allows the STDIN stream to be used as a private scratchpad to prepare data
for subsequent processing. For example,several files could be concatenated with
delimiters between them by simply reading the input files,PUSHing the lines
into the stream,and inserting a delimiter where required. Once the stacked
lines are exhausted,the stream reverts to its normal source of data.
Example:
/* Stack commands for compile and link*/
push "blink c.o+main.o library amiga.lib to myprog"
push "cc main"
36
4-23 QUEUE
Usage:QUEUE [expression]
The QUEUE instruction is used to prepare a stream of data to be read by a
command shell or other program. It is very similar to the preceding PUSH
instruction,and differs only that the data lines are placed in the STDIN stream
in "first-in,first-out" order. In this case the instruction
queue line 1
queue line 2
queue line 3
would be read in the order "line 1," "line 2," and "line 3." The QUEUEd lines
always precede all interactivly-entered lines,and always follow any PUSHed
(stacked)lines.
The same restriction noted with the use of the PUSH instruction apply to the
QUEUE instruction. The queueing mechanism uses the ACTION_QUEUE command,so the
DOS handler associated with the STDIN stream must support this command.
In most cases the choice of whether to use PUSH or QUEUE is just a matter of
convenience or personal preference. Each of them provides a "scratch pad"
facility similar to that provided by an I/O pipe,but useful within one program
or task rather than just for interprocess communications.
Example:
/* Queue commands for compile and link */
queue "cc main"
queue "blink c.o+main.o library amiga.lib to myprog"
4-24 RETURN
RETURN is used to leave a function and return control to the point of the
previous function invocation. The evaluated expression is returned as the
function result. If an expression is not supplied,an error may result in the
caller's environment. Functions called from within an expression must return a
result string,and will generate an error if no result is available. Function
invoked by the CALL instruction need not return a result.
A RETURN issued from the base environment of a program is not an error,and is
equivalent to an EXIT instruction. Refer to the EXIT instruction for a
description of how result strings are passed back to an external caller.
Example:
return 6*7 /*the answer */
37
4-25 SAY
Usage:SAY [expression]
The result of the evaluated expression is written to the output console,with a
"newline" character appended. If the expression is omitted,a null string is
sent to the console.
Example:
say 'The anwer is ' value
4-26 SELECT
Usage:SELECT
This instruction begins a group of instructions containing one or more WHEN
clauses and possibly a single OTHERWISE clause,each followed by a conditional
statement.
Only one of the conditional statements within the SELECT group will be
executed. Each WHEN statement is executed in succession until one succeeds;if
none succeeds,the OTHERWISE statement is executed. The SELECT range must be
terminated by an eventual END statement.
Example:
select
when i=1 then say 'one'
when i=2 then say 'two'
otherwise say 'other'
end
4-27 SHELL
Usage:SHELL [symbol | string] [expression]
The SHELL instruction is a synonym for the ADDRESS instruction.
Example:
shell edit /* set host to 'EDIT' */
4-28 SIGNAL
Usage: SIGNAL {ON |OFF} condition
or: SIGNAL [VALUE] expression
There are two forms of the SIGNAL instruction. The first form illustrated
controls the state of the internal interrupt flags. Interrupts allow a program
to detect and retain control when certain errors occur,and are discussed in
Chapter 7. In this form SIGNAL must be followed by one of the keywords ON or
OFF and one of the condition keywords listed below. The interrupt flag
specified by the condition symbol is then set to the indicated state. The valid
signal conditions are:
BREAK_C A "control-C" break was detected.
BREAK_D A "control-D" break was detected.
BREAK_E A "control-E" break was detected.
38
BREAK_F A "control-F" break was detected.
ERROR A Host command returned a non-zero code.
HALT An external HALT request was detected.
IOERR An error was detected by the I/O system.
NOVALUE An uninitialized variable was used.
SYNTAX A syntax or execution error was detected.
The condition keywords are interpreted as labels to which control will
transferred if the selected condition occurs. For example,if the ERROR
interrupt is enabled and a command returns a non-zero code,the interpreter will
transfer control to the label ERROR:. The condition label must of course be
defined in the program;otherwise,an immediate SYNTAX error results and the
program exits.
In the second form of the instruction,the tokens following SIGNAL are evaluated
as an expression. An immediate interrupt is generated that transfers control to
the label specified by the expression result. The instruction thus acts as a
"computed goto."
INTERRUPTS. Whenever an interrupt occurs,all currently active control ranges
(IF,DO,SELECT,INTERPRET,or interactive TRACE) are dismantled before the
transfer of control. Thus,the transfer cannot be used to jump into the range of
a DO-loop or other control structure. Only the control structures in the
current environment are affected by a SIGNAL condition,so it is safe to SIGNAL
from within an internal function without affecting the state of the caller's
environment.
SPECIAL VARIABLES. The special variable SIGL is set to the current line number
whenever a transfer of control occurs. The program can inspect SIGL to
determine which line was being executed before the transfer. If an ERROR or
SYNTAX condition causes an interrupt,the special variable RC is set to the
error code that triggered the interrupt. For the ERROR condition,this code is
usually an error secerity level. The SYNTAX condition will always indicate an
ARexx error code.
Examples:
signal on error /* enable interrupt */
signal off syntax /* disable SYNTAX */
signal start /* goto START */
4-29 THEN
Usage:THEN[;] [conditional statement]
The THEN instruction must be the next statement following an IF or WHEN
instruction,and is valid only in that context. It tests whether the preceding
expression evaluated to 1(True),in which case the conditional statement
following the THEN is performed. If the expression result was a 0(False),the
conditional statement is skipped.
39
Example:
if i=j
then say 'equal'
else say 'not equal'
4-30 TRACE
Usage:TRACE [symbol|string|[[VALUE] expression]]
The TRACE instruction is used to set the internal tracing mode. If a symbol or
string is supplied,it is taken as a literal. Otherwise,the tokens following the
VALUE keyword are evaluated as an expression. The VALUE keyword can be omitted
if the expression doesn't start with a symbol or string token.
In either case the result string is converted to uppercase and checked first
for one of the "alphabetic" options. The valid alphabetic options are ALL,
COMMANDS,ERRORS,INTERMEDIATES,LABELS,RESULTS,and SCAN. These can be spelled out
in full or shortened to the initial character,and are described in Chapter 7.
If the result doesn't match any of these options,the interpreter attempts to
convert it to an integer. A conversion failure here will be reported as an
error.
PREFIX CHARACTERS. Two special symbol characters may precede any of the
alphabetic keywords. The "?" character interactive tracing,and the "!"
character controls command inhibition. These characters act as "toggles" to
alternatively select and de-select the respective modes. Any number of prefix
characters may precede an alphabetic option. Interactive tracing and command
inhibition are described in Chapter 7.
NUMERIC OPTION. If the specified trace option is a negative whole number,it is
accepted as a trace suppression count. The suppression count is the number of
clauses(that would otherwise be traced)to be passed over before resuming the
tracing display. Suppression counts are ignored execept during interactive
tracing.
Examples:
trace ?r /* interactive RESULTS */
trace off
trace -20 /* skip 20 clauses */
4-31 UPPER
Usage:UPPER variable [variable...]
The values of the variables in the list are converted to uppercase. It is not
an error to include an uninitialized variable in the list,but it will be
trapped if the NOVALUE interrupt has been enabled.
The TRANSLATE() or UPPER() Built-In functions could also be used to convert
variables to uppercase,but the instruction form is more concise(and faster) if
several variables are being converted.
40
Example:
when='Now is the time'
upper when
say when /* NOW IS THE TIME */
4-32 WHEN
Usage:WHEN expression [THEN [;] [conditional statement]]
The WHEN instruction is similar to the IF instruction,but is valid only within
a SELECT range. Each WHEN expression is evaluated in turn and must result in a
boolean value. If the result is a 1,the conditional statement is executed and
control passes to the END statement that terminates the SELECT. As in the case
of the IF instruction,the THEN need not be part of the same clause.
Example:
select;
when i<j thn say 'less'
when i=j then say 'equal'
otherwise say 'greater'
end
41
CHAPTER 5 COMMANDS
The REXX language is unusual in that an entire syntactic class of program
statements are reserved for cmmands,statements that have meaning not within the
language itself but rather to an external program. When a command clause is
found in a program,it is evaluated as an expression and then sent through the
command interface to an explicit or implicit host application,an external
program that has announced its ability to receive commands. The host
application then processes the command and returns a result code that indicates
whether the command was performed successfully. In this manner every host
program becomes fully programmable,and with even a limited set of predefined
operations can be customized by the end user.
This chapter discusses the ARexx command interface and examines some of the
ways in which commands can be used to build programs for an external program.
Such programs are ofter called "macro programs" because they implement a
complex ("macro") action from a series of simpler "micro" commands.
Chapter 10 has detailed information on the data structers required to implement
a command interface for an applications program.
5-1 COMMAND CLAUSES
Syntactically,a command clause is just an expression that can't be classified
as another type of clause. The actual structure of the command is dictated by
the external host to which it is intended,but in most cases will follow the
model of a name or letter followed by parameter data. Command names can be
given as either a symbol or a string. However,it is generally safer to use a
string for the name,since it can't be assigned a value or be mistaken for an
instruction keyword. For example,the following might be commands for a text
editor:
JUMP current+10 /* advance to next */
'insert' newstring /* blast it in */
'TOP' /* back to the top */
Since command clauses are expressions,they are fully evaluated before being
sent to the host. Any part of the final command string can be computed within
the program,so virtually any sort of command structure can be created.
The interpretation of the received commands depends entirely on the host
application. In the simplest case the command strings will correspond exactly
to commands that could be entered directly by a user. For instance,positional
control(up/down)commands for a text editor would probably have identical
interpretations whether issued by the user or from a program. Other commands
may be valid only when issued from a macro program;a command to simulate a menu
operation would probably not be entered by the user.
43
5-2 THE HOST ADDRESS
The destination for a command is determined by the current host address,which
is the name of the public message port managed by an external program. ARexx
maintains two implicit host addresses,a "current" and a "previous" value,as
part of the program's storage environment. These values can be changed at any
time using the ADDRESS instruction(or its synonym,SHELL,)and the current host
address can be inspected with the ADDRESS()Built-In fuction. The default host
address string is "REXX",but this can be overridden when a program is invoked.
In particular,most host applications will supply the name of their public port
when they invoke a macro program,so that the macro can automatically issue
commands back to the host.
One special host address is recognized: the string COMMAND indicates that the
command should be issued directly to the underlying DOS. All other host
addresses are assumed to refer to a public message port. An attempt to send a
commmand to a non-existent message port will generate the syntax error "Host
environment not found."
Single commands can be sent to a specific host without disturbing the host
address settings. This is done using the ADDRESS instruction,as the following
example illustrates:
ADDRESS MYEDIT 'jump top'
This example would send the command "jump top" to an external host named
"MYEDIT."
It is important to note that you cannot send commands to a host application
without knowing the name of its public message port. Writing macro programs to
communicate with two or more hosts may require some clever programming to
determine whether both hosts are active and what their respective host
addresses are.
5-3 THE COMMAND INTERFACE
ARexx implements its command interface using the message-passing facilities
provided by the EXEC operating system. Each host application must provide a
public message port,the name of which is referred to as the host address. ARexx
programs issue commands by placing the command string in a message packet and
sending the packet to the host's message port. The program "sleeps" while the
host processes the command,and awakens when the message packet returns. The
entire process can be regarded as a dialogue between the host application and a
macro program:the host initiates the dialogue by invoking the macro,and the
macro program replies with one or more command strings. The commands that can
be sent are not limited to simple text strings,but might be address pointers or
even bit-mapped images.
After it finishes processing a command,the host "replies" the message packet
with a return code that indicates the status of the command. This return code
is placed in the ARexx special variable RC so that it can be examined by the
program. A value of zero is assumed to mean that no errors occurred,while
positive values usually indicate progressively more severe error conditions.
The return code allows the macro program to determine whether the command
succeeded and to take action if it failed,so it is important for each
applictions program to document the meanings of the return codes for its
commands.
44
5-4 USING COMMANDS IN MACRO PROGRAMS
ARexx can be used to write programs for any host application that includes a
suitable command interface. Some applications programs are designed with an
embedded macro language,and may include many predefined macro commands. With a
well-designed macro language interface the user will be usually unaware of
whether a given action is implemented as a primitive operations or as a macro
program.
The starting point in designing a macro program is to examine the commands that
would be required to perform it manually. The documentation for the host
application program should then describe the possible return codes for each
command;these codes can be used to determine whether the operation performed by
the command was successful. Check also for "shortcut" commands that may be
available only to macro programs;some applications programs may include very
powerful functions that were implemented specifically for use in macro
programs.
5-5 USING AREXX WITH COMMAND SHELLS
Although ARexx was designed to work most effectively with programs that support
its specific command interface,it can be used with any "command shell" program
that uses standards I/O mechanisms to obtain its input stream. There are
several ways to use ARexx to prepare a stream of commands for such program.
One obvious technique is to create an actual command file on the "RAM:" disk
and then pass it directly to the command shell. For example,you could open a
new CLI window to run a standard "execute" script using the following short
program:
/* Launch a new CLI */
address command
conwindow = "CON:0/0/640/100/NewOne"
/* create a command file on the fly */
call open out,"ram:$$temp",write
call writeln out,'echo "this is a test"'
call close out
/* open the new CLI window */
'newcli' conwindow "ram:$$temp"'
exit
Since no disk accesses are required,this method is actually fairly fast,if not
very elegant.
Another alternative is to use the command stacking facility provided by the
PUSH and QUEUE instructions. These instructions allow an ARexx program to stack
an arbitrary stream of commands and data for the command shell or other program
to read. Any set of commands that could be "typed ahead" at a command prompt
can be prepared in this fashion. After the ARexx program exits,the next program
that uses the input stream will read the prepared commands and can process them
in the normal fashion.
45
5-6 COMMAND INHIBITION
Sometimes it is necessary to write and test macro programs that issue
potentially destructive commands. For instance,a program to find and delete
unneeded files would be difficult to test safely,since it might accidentally
delete the wrong files and would require a continual source of new files for
testing.
To simply the development and testing of such programs,ARexx provides a special
tracing mode called command inhibition that suppresses host commands. While in
command inhibition mode,command processing proceeds normally except that the
command is not actually issued and the variable RC is set to 0. This allows the
program logic to be verified before any commands are actually sent to the
external program. Chapter 7 has further information on this facility.
46
CHAPTER 6 FUNCTIONS
The basic concept of a function is a program or group of statements that will
be executed whenever the function name appears in a certain context. Functions
are an important building block of most computer languages in that they allow
modular programming -- the ability to build a large program from a series of
smaller,more easily developed modules. In ARexx a function may be defined as
part of(internal to)a program,as part of a library,or as a separate external
program.
6-1 SYNTAX AND SEARCH ORDER
Function calls in an expression are defined syntactically as a symbol or string
followed immediately by an open parenthesis. The symbol or string(taken an a
literal)specifies the function name,and the open parenthesis begins the
argument list. Between the opening and eventual closing parentheses are zero or
more argument expressions,separated by commas,that supply the data being passed
to the function. For example,
CENTER('title",20)
ADDRESS()
'AllocMem'(256*4,1)
are all valid function calls. Each argument expression is evaluated in turn and
the resulting strings are passed as the argument list to the function. There is
no limit to the number of arguments that may be passed to an internal
function,but calls to Built-In or external functions are limited to a maximum
of 15 arguments. Note that each argument expression,while ofter just a single
literal value,can include arithmetic or string operations or even other
function calls. Argument expressions are evaluated from left to right.
Functions can also be invoked using the CALL instruction. The syntax of this
form is slightly different,and is described in Chapter 4. The CALL instruction
can be used to invoke a function that may not return a value.
SEARCH ORDER
Function linkages in ARexx are established dynamically at the time of the
function call. A specific search order is followed until a function matching
the name symbol or string is found. If the specified function cannot be
located, an error is generated and the expression evaluation is terminated. The
full search order is:
1. Internal Functions. The program source is examined for a label that matches
the function name. If a match is found,a new storage environment is created and
control is transferred to the label.
2. Built-In Functions. The Build-In function library is searched for the
specified name. All of these functions are defined by uppercase names,and the
library has been specially organized to make the search as efficient as
possible.
47
3. Function Libraries and Function Hosts. The available function libraries and
function hosts are maintained in a prioritized list,which is searched starting
at the highest priority until the requested function is found or the end of the
list is reached. Each function library is opened and called at a special entry
point to determine whether it contains a function matching the given name.
Function hosts are called using a message-passing protocol similar to that used
for commands,and may be used as gateways for remote procedure calls to other
machines in a network.
4. External ARexx Programs. The final search step is to check for an external
ARexx program file by sending an invocation message to the ARexx resident
process. The search always begins in the current directory,and follows the same
search path as the original ARexx program invocation. The name matching process
is not case-sensitive.
Note that the function name-matching procedure may be case-sensitive for some
of the search steps but not for others. The matching procedure used in a
function library or function host is left to the discretion of the applications
designer. Functions defined with mixed-case names must be called using a string
token,since symbol names are always translated to uppercase.
The full search order is followed whenever the function name is defined by a
symbol token. However,the search for internal functions is bypassed if the name
is specified by a string token. This allows internal functions to usurp the
names of external functions,as in the following example:
CENTER: /* internal "CENTER" */
arg string,length /* get arguments */
length = min(length,60) /* compute length */
return 'CENTER'(string,length)
Here the Built-In fuction CENTER()has been replaced by an internal function of
the same name,which calls the original function after modifying the length
argument.
INTERNAL FUNCTIONS
The interpreter creates a new storage environment when an internal function is
called,so that the previous(caller's)environment is preserved. The new
environment inherits the values from its predecessor,but subsequent changes to
the environment variables do not affect the previous environment. The specific
values that are preserved are:
The current and previous host addresses,
The NUMERIC DIGITS,FUZZ,and FORM settings,
The trace option,inhibit flag,and interace flag,
The state of the interrupt flags defined by the SIGNAL instruction,and
The current prompt string as set by the OPTIONS PROMPT instruction.
The new environment does not automatically get a new symbol table,so initially
all of the variables in the previous environment are available to the called
function. The PROCEDURE instruction can be used to create a new symbol table
48
and thereby protect the caller's symbol values.
Execution of the internal function proceeds until a RETURN instruction is
executed. At this point the new environment is dismantled and control resumes
at the point of the function call. The expression supplied with the RETURN
instruction is evaluated and passed back to the caller as the fuction result.
BUILT-IN FUNCTIONS
ARexx provides a substantial library of predefined functions as part of the
language system. These functions are always available and have been optimized
to work with the internal data structures. In general the Built-In functions
execute much faster than an equivalent interpreted function,so their usage is
strongly recommended.
The Built-In Function Library is not user-extensible,but additional functions
will be included in later releases.
EXTERNAL FUNCTION LIBRARIES
External function libraries provide a mechanism with which users and
applications developers can extend the functionality of ARexx. A function
library is a collection of one or more functions together with a "query" entry
point that serves to match a name string with the appropriate function.
External function libraries are supported as standard Amiga shared libraries,
and may be either memory or disk-resident. Disk-resident libraries are loaded
and opened as needed.
The ARexx resident process maintains a list,called the Library List,of the
currently available function libraries and function hosts. Applications
programs can add or remove function libraries as required. The Library List is
maintained as a priority-sorted queue,and entries can be added at an
appropriate priority to control the function name resolution. Libraries with
higher priorities are searched first;within a given priority level,those
libraries added first are searched first.
During the search process the ARexx interpreter opens each library and calls
its "query" entry point. The query function must then check to see whether the
requested function name is in the library. If not,it returns a "function not
found" error code and the search continues with the next library in the list.
Function libraries are always closed after being checked so that the operatiing
system can reclaim the memory space if required. Once the requested function
has been found,it is called with the arguments passed by the interpreter,and
must return an error code and a result string.
The ARexx language system includes an external function library in a file
called "rexxsupport.library". It contains a number of Amiga-specific functions
and is described in Appendix D. Chapter 10 provides information on designing
and implementing function libraries.
49
FUNCTION HOSTS
Function hosts are called by sending a function invocation message packet to
the public message port identified by the host's name. No constraints are
imposed on the iternal design of the host except that it must eventually return
the invocation message with an appropriate return code and result string. The
function call may result in a new program being loaded and run,or might even be
sent to a network handler as a remote procedure call.
The available function hosts,along with the function libraries,are contained in
the Library List maintained by the resident process. This list provides a
general mechanism for resolving function names in a priority-controlled manner.
The ARexx resident process is an example of a function host. It is added to the
Library List at a nominal priority of -60 when the resident process is started,
using the same name ("REXX")that is used for command invocations. When it
receives a function invocation packet,it searches for an external file matching
the function name,just as it would for a command invocation of the same name.
In particular,the search begins with the current directory and process is not
case-sensitive,but is affected by the presence of explicit directory
specifications or file extensions in the name string. The rules governing the
search for external programs are covered in Chapter 9.
External programs are always run as a separate process in the Amiga's
multitasking system. The calling program "sleeps" until the called function
finishes and the message packet returns. The result string and error code are
returned in the packet.
6-2 THE BUILT-IN FUNCTION LIBRARY
This section of the chapter is devoted to descriptions of the individual Built
In functions,which are listed alphabetically. Many of the functions have
optional as well as required arguments. The optional arguments are shown in
brackets,and generally have a default value that is used if the argument is
omitted.
MAXIMUM ARGUMENTS. While internal functions can be called with any number of
arguments,the Built-In functions(and external functions as well)are limited to
a maximum of 15 arguments.
PAD AND OPTION CHARACTERS. For functions that accept a "pad" character
argument,only the first character of the argument string is significant. If a
null string is supplied,the default padding character(usually a blank)will be
used. Similarly,where an option keyword is specified as an argument,only the
first character is significant. Option keywords may be given in uppercase or
lowercase.
I/O SUPPORT FUNCTIONS. ARexx provides functions for creating and manipulating
external DOS files. The functions available at the present time are OPEN(),
CLOSE(),READCH(),READLN(),WRITECH(),WRITELN(),EOF(),SEEK(),and EXISTS(). Files
are referenced by a "logical name," a case-sensitive name that is assigned to a
file when it is first opened.
50
There is no limit to the number of files that may be open simultaneously,and
all open files are closed automatically when the program exits.
BIT-MANIPULATION FUNCTIONS. The functions BITCHG(),BITCLR(),BITCOMP(),BITSET(),
and BITTST() are provided to implement extended bit-testing on character
strings. These functions differ from similar string-manipulation functions in
that the elementary unit of comparison is the bit rather than the byte. Bit
number are defined such that bit 0 is the low-order bit of the rightmost byte
of the string.
ABBREV()
Usage:ABBREV(string1,string2,[length]
Returns a boolean value that indicates whether string2 is an abbreviation of
string1 with length greater than or equal to the specified length argument. The
default length is 0,so the null string is an acceptable abbreviation.
Example:
say abbrev('fullname','ful' ==>1
say abbrev('almost','alm',4) ==>0
say abbrev('any','') ==>1
ABS()
Usage:ABS(number)
Returns the absolute value of the number argument,which must be numeric.
Examples:
say abs(-5.35) ==>5.35
say abs(10) ==>10
ADDLIB()
Usage ADDLIB(name,priority,[offset,version])
Adds a function library or a function host to the Library List maintained by
the resident process. The name argument specifies either the name of a function
library or the public message port associated with a function host. The name is
case-sensitive,and any libraries thus declared should reside in the system
LIBS: directory. The priority argument specifies the search priority and must
be an integer between 100 and -100,inclusive. The offset and version arguments
apply only to libraries. The offset is the integer offset to the library's
"query" entry point,and the version is an integer specifying the minimum
acceptable release level of the library.
The function returns a boolean result that indicates whether the operation was
successful. Note that if a library is specified,it is not actually opened at
this time;similarly,no check is performed as to whether a specified function
host port has been opened yet.
Example:
say addlib("rexxsupport.library",0,-30,0)==>1
call addlib "EtherNet",-20 /* a gateway */
51
ADDRESS()
Usage:ADDRESS()
Returns the current host address string. The host address is the message port
to which commands will be sent. The SHOW()function can be used to check whether
the required external host is actually available.
See Also:SHOW()
Example:
say address() ==>REXX
ARG()
Usage:ARG([number],['Exists' | 'Omitted'])
ARG()returns the number of arguments supplied to the current environment. If
the number parameter alone is supplied,the corresponding argument string is
returned. If a number and one of the keywords Exists or Omitted is given,the
boolean return indicates the status of the corresponding argument. Note that
the existence or omission test does not indicate whether the string has a null
value,but only whether a string was supplied.
Examples:
/* Assume arguments were: ('one,,10) */
say arg() ==>3
say arg(1) ==>one
say arg(2,'0') ==>1
B2C()
Usage:B2C(string)
Converts a string of binary digits(0,1)into the corresponding(packed)character
representation. The conversion is the same as though the argument string had
been specified as a literal binary string(e.g. '1010'B). Blanks are permitted
in the string,but only at byte boundaries. This function is particularly useful
for creating strings that are to be used as bit masks.
See also:X2C()
Examples:
say b2c('00110011') ==>3
say b2c('01100001') ==>a
BITAND()
Usage:BITAND(string1,string2,[pad])
The argument strings are logically ANDed together,with the length of the result
being the longer of the two operand strings. If a pad character is supplied,the
shorter string is padded on the right;otherwise,the operation terminates at the
end of the shorter string and the remainder of the longer string is appended to
the result.
Example:
bitand('0313'x,'FFF0'x) ==>'0310'x
52
BITCHG()
Usage:BITCHG(string,bit)
Changes the state of the specified bit in the argument string. Bit numbers are
defined such that bit 0 is the low-order bit of the rightmost byte of the
string.
Example:
bitchg('0313'x,4) ==>'0303'x
BITCLR()
Usage:BITCLR(string,bit)
Clears(sets to zero)the specified bit in the argument string. Bit numbers are
defined such that bit 0 is the low-order bit of the rightmost byte of the
string.
Example:
bitclr('0313'x,4) ==>'0303'x
BITCOMP()
Usage:BITCOMP(string1,string2,[pad])
Compares the argument strings bit-by-bit,starting at bit number 0. The returned
value is the bit number of the first bit in which the strings differ,or -1 if
the strings are identical.
Examples:
bitcomp('7F'x,'FF'x) ==>7
bitcomp('FF'x,'FF'x) ==>-1
BITOR()
Usage:BITOR(string1,string2,[pad])
The argument strings are logically ORed together,with the length of the result
being the longer of the two operand strings. If a pad character is supplied,the
shorter string is padded on the right;otherwise,the operation terminates at the
end of the shorter string and the remainder of the longer string is appended to
the result.
Example:
bitor('0313'x,'003F'x) ==>'033F'x
BITSET()
Usage:BITSET(string,bit)
Sets the specified bit in the argument string is 1. Bit numbers are defined
such that bit 0 is the low-order bit of the rightmost byte of the string.
Example:
bitset('0313'x,2) ==>'0317'x
BITTST()
Usage:BITTST(string,bit)
The boolean return indicates the state of the specified bit in the argument
string.
53
Bit numbers are defined such that bit 0 is the low-order bit of the rightmost
byte to the string.
Example:
bittst('0313'x,4) ==>1
BITXOR()
Usage:BITAND(string1,string2,[pad])
The argument strings are logically exclusively-ORed together,with the length of
the result being the longer of the two operand strings. If a pad character is
supplied,the shorter string is padded on the right;otherwise,the operation
terminates at the end of the shorter string and the remainder of the longer
string is appended to the result.
Example:
bitxor('0313'x,'001F'x) ==>'030C'x
C2B()
Usage:C2B(string)
Converts the character string into the equivalent string of binary digits.
See Also:C2X()
Example:
say c2b('abc') ==>011000010110001001100011
C2D()
Usage:C2D(string,[n])
Converts the string argument from its character representation to the
corresponding decimal number,expressed as ASCII digits(0-9). If n is supplied,
the character string is considered to be a number expressed in n bytes. The
string is truncated or padded with nulls on the left as required,and the sign
bit is extended for the conversion.
Examples:
say c2d('0020'x) ==>32
say c2d('FFFF') ==>1
say c2d('FF0100',x,2) ==>256
C2X()
Usage:C2X(string)
Converts the string argument from its character representation to the
corresponding hexadecimal number,expressed as the ACSII characters 0-9 and A-F.
See Also:C2B()
Example:
say c2x('abc') ==>616263
54
CENTER() or CENTRE()
Usage:CENTER(string,length,[pad])or CENTRE(string,length,[pad])
Centers the string argument in a string with the specified length. If the
length is longer than that of the string,pad characters or blanks are added as
necessary.
Examples:
say center('abc',6) ==>' abc '
say center('abc',6,'+') ==>'+abc++'
say center('123456',3) ==>'234'
CLOSE()
Usage:CLOSE(file)
Closes the file specified by the given logical name. The returned value is a
boolean success flag,and will be 1 unless the specified file was not open.
Example:
say close('input') ==>1
COMPRESS()
Usage:COMPRESS(string,[list])
If the list argument is omitted,the function removes leading,trailing,or
embedded blank characters from the string argument. If the optional list is
supplied,it specifies the characters to be removed from the string.
Examples:
say compress (' why not ') ==>whynot
say compress ('++12-34-+','+-') ==>1234
COMPARE()
Usage:COMPARE(string1,string2,[pad])
Compares two strings and returns the index of the first position in which they
differ,or 0 if the strings are identical. The shorter string is padded as
required using the supplied character or blanks.
Examples:
say compare('abcde','abcce') ==>4
say compare('abcde',abcde') ==>0
say compare('abc++','abc+-','+') ==>5
COPIES()
Usage:COPIES(string,number)
Creates a new string by concatenating the specified number of copies of the
original. The number argument may be zero,in which case the null string is
returned.
55
Example:
say copies('abc',3) ==>abcabcabc
D2C()
Usage:D2C(number)
Creates a string whose value is the binary(packed)representation of the given
decimal number.
Example:
d2c(31) ==>'1F'x
DATATYPE()
Usage:DATATYPE9string,[option])
If the option parameter is not specified,DATATYPE()tests whether the string
parameter is a valid number and returns either NUM or CHAR. If an option
keyword is given,the boolean return indicates whether the string satisfied the
requested test. The following option keywords are recognized:
Table 6.1 DATATYPE()Options
KEYWORD CHARACTERS ACCEPTED
Alphanumeric Alphabetics (A-Z,a-z)
or Numerics (0-9)
Binary Binary Digits String
Lowercase Lowercase Alphabetics (a-z)
Mixed Mixed Upper/Lowercase
Numeric Valid Numbers
Symbol Valid REXX Symbols
Upper Uppercase Alphabetics (A-Z)
Whole Integer Numbers
X Hex Digits String
Examples:
say datatype('123') ==>NUM
say datatype('1a f2','x') ==>1
say datatype('aBcde','L') ==>0
DELSTR()
Usage:DELSTR(string,n,[length])
Deletes the substring of the string argument beginning with the nth character
for the specified length in characters. The default length is the remaining
length of the string.
Example:
say delstr('123456',2,3) ==>156
56
DELWORD()
Usage:DELWORD(string,n,[length])
Deletes the substring of the string argument beginning with the nth word for
the specified length in words. The default length is the remaining length of
the string. The deleted string includes any trailing blanks following the last
word.
Examples:
say delword('Tell me a story',2,2)==>'Tell story'
say delword('one two three',3) ==>'one two '
EOF()
Usage:EOF(file)
Checks the specified logical file name and returns the boolean value 1(True)if
the end-of-file has been reached,and 0(False)otherwise.
Example:
say eof(infile) ==>1
ERRORTEXT()
Usage:ERRORTEXT(n)
Returns the error message associated with the specified ARexx code. The null
string is returned if the number is not a valid error code.
Example:
say errortext(41) ==>Invalid expression
EXISTS()
Usage:EXISTS(filename)
Tests whether an external file of the given filename exists. The name string
may include device and directory specifications.
Example:
say exists('df0:c/ed') ==>1
EXPORT()
Usage:EXPORT(address,[string],[length],[pad])
Copies data from the (optional) string into a previously-allocated memory area,
which must be specified as a 4-byte address. The length parameter specifies the
maximum number of characters to be copied; the default is the length of the
string. If the specified length is longer than the string,the remaining area is
filled with the pad character or nulls('00'x). The returned value is the number
of characters copied.
Caution is advised in using this function. Any area of memory can be
overwritten,possibly causing a system crash. Task switching is forbidden while
the copy is being done,so system performance may be degraded if long strings
are copied.
See Also:IMPORT(),STORAGE()
57
Example:
count = export('0004 0000'x,'The answer')
FREESPACE()
Usage:FREESPACE(address,length)
Returns a block of memory of the given length to the interpreter's internal
pool. The address argument must be a 4-byte string obtained by a prior call to
GETSPACE(),the internal allocator. It is not always necessary to release
internally-allocated memory,since it will be released to the system when the
program terminates. However,if a very large block has been allocated,returning
it to the pool may avoid memory space problems. The return value is a boolean
success flag.
See Also:GETSPACE()
Example:
say freespace('00042000'x,32) ==>1
GETCLIP()
Usage:GETCLIP(name)
Searches the Clip List for an entry matching the supplied name parameter,and
returns the associated value string. The name-matching is case-sensitive,and
the null string is returned if the name cannot be found. The usage and
maintenance of Clip List entries is described in the Chapter 9.
See Also:SETCLIP()
Example:
/* Assume 'numbers' contains 'PI=3.14159' */
say getclip('numbers') ==>PI=3.14159
GETSPACE()
Usage:GETSPACE(length)
Allocates a block of memory of the specified length from the interpreter's
internal pool. The returned value is the 4-byte address of the allocated block,
which is not cleared or otherwise initialized. Internal memory is automatically
returned to the system when the ARexx program terminates,so this function
should not be used to allocate memory for use by external programs. The Support
Library(described in Appendix D)includes the function ALLOCMEM()which to
allocate memory from the system free list.
See Also:FREESPACE()
Example:
say c2x(getspace(32)) ==>'0003BF40'x
HASH()
Usage:HASH(string)
Returns the hash attribute of a string as a decimal number,and updates the
internal hash value of the string.
58
Example:
say hash('1') ==>49
IMPORT()
Usage:IMPORT(address,[length])
Creates a string by copying data from the specified 4-byte address. If the
length parameter is not supplied,the copy terminates when a null byte is found.
See Also:EXPORT()
Example:
extval = import('0004 0000'x,8)
INDEX()
Usage:INDEX(string,pattern,[start])
Searches for the first occurrence of the pattern argument in the string
argument,beginning at the specified start position. The default start position
is 1. The returned value is the index of the matched pattern,or 0 if the
pattern was not found.
Examples:
say index("123456","23") ==>2
say index("123456","77") ==>0
say index("123123","23",3) ==>5
INSERT()
Usage:INSERT(new,old,[start],[length],[pad])
Inserts the new string into the old string after the specified start position.
The default starting position is 0. The new string is truncated or padded to
the specified length as required,using the supplied pad character or blanks. If
the start position is beyond the end of the old string,the old string is padded
on the right.
Examples:
say insert('ab,'12345') ==>ab12345
say insert('123','++',3,5,'-') ==>++-123--
LASTPOS()
Usage:LASTPOS(pattern,string,[start])
Searches backwards for the first occurrence of the pattern argument in the
string argument,beginning at the specified start position. The default starting
position is the end of the string. The returned value is the index of the
matched pattern,or 0 if the pattern was not found.
59
Examples:
say lastpos("123234","2") ==>4
say lastpos("123234","5") ==>0
say lastpos("123234","2",3) ==>2
LEFT()
Usage:LEFT(string,length,[pad])
Returns the leftmost substring in the given string argument with the specified
length. If the substring is shorter than the requested length,it is padded on
the left with the supplied pad character or blanks.
Examples:
say left('123456',3) ==>123
say left('123456',8,'+') ==>123456++
LENGTH()
Usage:LENGTH(string)
Returns the length of the string.
Example:
say length('three') ==>5
MAX()
Usage:MAX(number,number[,number,...])
Returns the maximum of the supplied arguments,all of which must be numeric. At
least two parameters must be supplied.
Example:
say max(2.1,3,-1_ ==>3
MIN()
Usage:MIN(number,number[,number,...])
Returns the minimum of the supplied arguments,all of which must be numeric. At
least two parameters must be supplied.
Example:
say min(2.1,3,-1) ==>-1
OPEN()
Usage:OPEN(file,filename,['Append' | 'Read' | 'Write'])
Opens an external file for the specified operation. The file argument defines
the logical name by which the file will be referenced. The filename is the
external name of the file,and may include device and directory specifications.
The function returns a boolean value that indicates whether the operation was
successful. There is no limit to the number of files that can be open
60
simultaneusly,and all open files are closed automatically when the program
exits.
See Also:CLOSE(),READ(),WRITE()
Examples:
say open('MyCon','CON:160/50/320/100/MyCon/cds') ==>1
say open('outfile','ram:temp','W') ==>1
OVERLAY()
Usage:OVERLAY(new,old,[start],[length],[pad])
Overlays the new string onto the old string beginning at the specified start
position,which must be positive. The default starting position is 1. The new
string is truncated or padded to the specified length as required,using the
supplied pad character or blanks. If the start position is beyond the end of
the old string,the old string is padded on the right.
Examples:
say overlay('bb,'abcd') ==>bbcd
say overlay('4','123',5,5,'-') ==>123--4----
POS()
Usage:POS(pattern,string,[start])
Searches for the first occurrence of the pattern argument in the string
argument,beginning at the position specified by the start argument. The default
starting position is 1. The returned value is the index of the matched
string,or 0 if the pattern wasn't found.
Examples:
say pos('23','123234') ==>2
say pos('77','123234') ==>0
say pos('23','123234',3) ==>4
PRAGMA()
Usage:PRAGMA(option,[value])
This function allows a program to change various attributes relating to the
system environment within which the program executes. The option argument is a
keyword that specifies an environmental attribute;the currently implemented
options are Directory and Priority. The value argument supplies the new
attribute value to be installed. The value returned by the function depends on
the attribute selected. Some attributes return the previous value
installed,while others may simply set a boolean success flag. The currently
defined option keywords are listed below.
DIRECTORY. Specifies a new "current" directory. The current directory is used
as the "root" for filenames that do not explicitly include a device
specification. The return value is a boolean success flag.
PRIORITY. Specifies a new task priority. The priority value must be an integer
in the range -128 to 127,but the practical range is much more limited. ARexx
programs should never be run at a priority higher than that of the resident
process,which currently runs at priority 4. The returned value is the previous
priority level.
61
Examples:
say pragma('priority',-5) ==>0
call pragma 'Directory','df0:system'
RANDOM()
Usage:RANDOM([min],[max],[seed])
Returns a pseudorandom integer in the interval specified by the min and max
arguments. The default minimum value is 0 and the default maximum value is 999.
The interval max-min must be less than or equal to 1000. If a greater range of
random integers is required,the values from the RANDU()function can be suitable
scaled and translated.
The seed argument can be supplied to initialize the internal state of the
random number generator.
See Also:RANDU()
Example:
thisroll = random(1,6) /* might be 1 */
nextroll = random(1,6) /* snake eyes? */
RANDU()
Usage:RANDU([seed])
Returns a uniformly-distributed pseudorandom number between 0 and 1. The number
of digits of precision in the result is always equal to the current Numeric
Digits setting. With the choice of suitable scaling and translation values,
RANDU()can be used to generate pseudorandom numbers on an arbitrary interval.
The optional seed argument is used to initialize the internal state of the
random number generator.
See Also:RANDOM()
Example:
firsttry = randu() /* 0.371902021? */
numeric digits 3
tryagain = randu() /* 0.873? */
READCH()
Usage:READCH(file,length)
Reads the specified number of characters from the given logical file into a
string. The length of the returned string is the actual number of characters
read,and may be less than the requested length if,for example,the end-of-file
was reached.
See Also:READLN()
Example:
instring = readch('input',10)
62
READLN()
Usage:READLN(file)
Reads characters from the given logical file into a string until a "newline"
character is found. The returned string does not include the "newline".
See Also:READCH()
Examples:
instring = readln('MyFile')
REMLIB()
Usage:REMLIB(name)
Removes an entry with the given name from the Library List maintained by the
resident process. The boolean return is 1 if the entry was found and
successfully removed. Note that this function does not make a distinction
between function libraries and function hosts,but simply removes a named entry.
See Also:ADDLIB()
Example:
say remlib('MyLibrary.library')==>1
REVERSE()
Usage:REVERSE(string)
Reverses the sequence of characters in the string.
Example:
say reverse('?ton yhw') ==>why not?
RIGHT()
Usage:RIGHT(string,length,[pad])
Returns the rightmost substring in the given string argument with the specified
length. If the substring is shorter than the requested length,it is padded on
the left with the supplied pad character or blanks.
Examples:
say right('123456',4) ==>3456
say right('123456',8,'+') ==>++123456
SEEK()
Usage:SEEK(file,offset,['Begin' | 'Current' | 'End'])
Moves to a new position in the given logical file,specified as an offset from
an anchor position. The default anchor is Current. The returned value is the
new position relative to the start of the file.
Examples:
say seek('input',10,'B') ==>10
say seek('input',O,'E') ==>356 /* file length */
63
SETCLIP()
Usage:SETCLIP(name,[value])
Adds a name-value pair to the Clip List maintained by the resident process. If
an entry of the same name already exists,its value is updated to the supplied
value string. Entries may be removed by specifying a null value. The function
returns a boolean value that indicates whether the operation was successful.
Examples:
say setclip('path','df0:s') ==>1
say setclip('path') ==>1
SHOW()
Usage:SHOW(option,[name],[pad])
Returns the names in the resource list specified by the option argument,or
tests to see whether an entry with the specified name is available. The
currently implemented options keywords are Clip,Files,Libraries,and Ports,
which are described below.
Clip. Examines the names in the Clip List.
Files. Examines the names of the currently open logical file names.
Libraries. Examines the names in the Library List,which are either function
libraries or function hosts.
Ports. Examine the names in the system Ports List.
If the name argument is omitted,the function returns a string with the resource
names separated by a blank space or the pad character,if one was supplied. If
the name argument is given,the returned boolean value indicates whether the
name was found in the resource list. The name entries are case-sensitive.
SIGN()
Usage:SIGN(number)
Returns 1 if the number argument is positive or zero,and -1 if number is
negative. The argument must be numeric.
Examples:
say sign(12) ==>1
say sign(-33) ==>-1
SPACE()
Usage:SPACE(string,n,[pad])
Reformats the string argument so that there are n spaces(blank characters)
between each pair of words. If the pad character is specified,it is used
instead of blanks as the separator character. Specifying n as 0 will remove all
blanks from the string.
Examples:
say space('Now is the time',3) ==>'Now is the time'
say space('Now is the time',0) ==>'Nowisthetime'
say space('1 2 3',1,'+') ==>'1+2+3'
64
STORAGE()
Usage:STORAGE([address],[string],[length],[pad])
Calling STORAGE()with no arguments returns the available system memory. If the
address argument is given,it must be a 4-byte string,and the function copies
data from the(optional)string into the indicated memory area. The length
parameter specifies the maximum number of bytes to be copied,and defaults to
the length of the string. If the specified length is longer than the string,the
remaining area is filled with the pad character or nulls('00'x.)
The returned value is the previous contents of the memory area. This can be
used in a subsequent call to restore the original contents.
Caution is advised in using this function. Any area of memory can be
overwritten,possibly causing a system crash. Task switching is forbidden while
the copy is being done,so system performance may be degraded if long strings
are copied.
See Also:EXPORT()
Examples:
say storage() ==>248400
oldval = storage('0004 000'x,'The answer')
call storage '0004 0000'x,,32,'+'
STRIP()
Usage:STRIP(string,[{'B' | 'L' | 'T'}],[pad])
If neither of the optional parameters is supplied,the function removes both
leading and trailing blanks from the string argument. The second argument
specifies whether Leading,Trailing,or Both(leading and trailing)characters are
to be removed. The optional pad(or unpad,perhaps)argument selects the character
to be removed.
Examples:
say strip(' say what? ') ==>'say what?'
say strip(' say what? ','L') ==>'say what? '
say strip('++123+++','B','+') ==>'123'
SUBSTR()
Usage:SUBSTR(string,start,[length],[pad])
Returns the substring of the string argument beginning at the specified start
position for the specified length. The starting position must be positive,and
the default length is the remaining length of the string. If the substring is
shorter than the requested length,it is padded on the left with the blanks or
the specified pad character.
Examples:
say substr('23456',4,2) ==>45
say substr('myname',3,6,'=') ==>name==
65
SUBWORD()
Usage:SUBWORD(string,n,[length])
Returns the substring of the string argument beginning with the nth word for
the specified length in words. The default length is the remaining length of
the string. The returned string will never have leading or trailing blanks.
Example:
say subword('Now is the time ',2,2) ==>is the
SYMBOL()
Usage:SYMBOL(name)
Tests whether the name argument is a valid REXX symbol. If the name is not a
valid symbol,the function returns the string BAD. Otherwise,the returned string
is LIT if the symbol is uninitialized and VAR if it has been assigned a value.
Examples:
say symbol('J') ==>VAR
say symbol('x') ==>LIT
say symbol('++') -->BAD
TIME()
Usage:TIME(option)
Returns the current system time or controls the internal elapsed time counter.
The valid option keywords are listed below.
Table 6.2 TIME()Options
OPTION KEYWORD DESCRIPTION
Elapsed Elapsed time in seconds.
Hours Current time in hours since midnight
Minutes Current time in minutes since midnight
Reset Reset the elapsed time clock
Seconds Current time in seconds since midnight
If no option is specified,the function returns the current system time in the
form HH:MM:SS.
Examples:
/* Suppose that the time is 1:02 AM ... */
say time('Hours') ==>1
say time('m') ==>62
say time('S') ==>3720
call time 'R' /* reset timer */
say time('E') ==>.020
66
TRACE()
Usage:TRACE(option)
Sets the tracing mode to that specified by the option keyword,which must be one
of the valid alphabetic or prefix options. The tracing options are described in
Chapter 7. The TRACE()function will alter the tracing mode even during
interactive tracing,when TRACE instructions in the source program are ignored.
The returned value is the mode in effect before the function call;this allows
the previous trace mode to be restored later.
Example:
/* Assume tracing mode is ?AL */
say trace('Results') ==>?A
TRANSLATE()
Usage:TRANSLATE(string,[output],[input],[pad])
This function constructs a translation table and uses it to replace selected
characters in the argument string. If only the string argument is given,it is
translated to uppercase. If an input table is supplied,it modifies the
translation table so that characters in the argument string that occur in the
input table are replaced with the corresponding character in the output table.
Characters beyond the end of the output table are replaced with the specified
pad character or a blank.
Note that the result string is always of the same length as the original
string. The input and output tables may be of any length.
Examples:
say translate("abcde","123","cbade","+") ==>321++
say translate("low") ==>LOW
say translate("0110","10","01") ==>1001
TRIM()
Usage:TRIM(string)
Removes trailing blanks from the string argument.
Example:
say length(trim(' abc ')) ==>4
UPPER()
Usage:UPPER(string)
Translates the strip to uppercase. The action of this function is equivalent to
that of TRANSLATE(string),but it is slightly faster for short strings.
Example:
say upper('One Fine Day') ==>ONE FINE DAY
67
VALUE()
Usage:VALUE(name)
Returns the value of the symbol represented by the name argument.
Example:
/* Assume that J has the value of 12 */
say value('j') ==>12
VERIFY()
Usage:VERIFY(string,list,['Match'])
If the Match argument is omitted,the function returns the index of the first
character in the string argument which is not contained in the list argument,or
0 if all of the characters are in the list. If the Match keyword is supplied,
the function returns the index of the first character which is in the list,or 0
if none of the characters are.
Examples:
say verify('123456','0123456789') ==>0
say verify('123a56','0123456789') ==>4
say verify('123a45','abcdefghij','m') ==>4
WORD()
Usage:WORD(string,n)
Returns the nth word in the string argument,or the null string if there are
fewer than n words.
Example:
say word('Now is the time ',2) ==>is
WORDINDEX()
Usage:WORINDEX(string,n)
Returns the starting position of the nth word in the argument string,or 0 if
there are fewer than n words.
Example:
say wordindex('Now is the time ',3) ==>8
WORDLENGTH()
Usage:WORDLENGTH(string,n)
Returns the length of the nth word in the string argument.
Example:
say wordlength('one two three',3) ==>5
68
WORDS()
Usage:WORDS(string)
Returns the number of words in the string argument.
Example:
say words("You don't say!") ==>3
WRITECH()
Usage:WRITECH(file,string)
Writes the string argument to the given logical file. The returned value is the
actual number of characters written.
Example:
say writech('output','Testing') ==>7
WRITELN()
Usage:WRITELN(file,string)
Writes the string argument to the given logical file with a "newline" appended.
The returned value is the actual number of characters written.
Example:
say writeln('output','Testing') ==>8
X2C()
Usage:X2C(string)
Converts a string of hex digits into the(packed)character representation. Blank
characters are permitted in the argument string at byte boundaries.
Examples:
say x2c('12ab') ==>'12ab'x
say x2c('12 ab') ==>'12ab'x
XRANGE()
Usage:XRANGE([start],[end])
Generates a string consisting of all characters numerically between the
specified start and end values. The default start character is '00'x,and the
default end character is 'FF'x. Only the first character of the start and end
arguments is significant.
Examples:
say xrange() ==>'00010203 ... FDFEFF'x
say xrange('a','f') ==>'abcdef'
say xrange(,'10'x) ==>'00010203040506070809010'x
69
NOW LOAD PART 2
end.